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

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

Issue 446743003: Hook up new API for easy unlock to update lock screen (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview User pod row implementation. 6 * @fileoverview User pod row implementation.
7 */ 7 */
8 8
9 cr.define('login', function() { 9 cr.define('login', function() {
10 /** 10 /**
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 * Variables used for pod placement processing. Width and height should be 48 * Variables used for pod placement processing. Width and height should be
49 * synced with computed CSS sizes of pods. 49 * synced with computed CSS sizes of pods.
50 */ 50 */
51 var POD_WIDTH = 180; 51 var POD_WIDTH = 180;
52 var PUBLIC_EXPANDED_BASIC_WIDTH = 500; 52 var PUBLIC_EXPANDED_BASIC_WIDTH = 500;
53 var PUBLIC_EXPANDED_ADVANCED_WIDTH = 610; 53 var PUBLIC_EXPANDED_ADVANCED_WIDTH = 610;
54 var CROS_POD_HEIGHT = 213; 54 var CROS_POD_HEIGHT = 213;
55 var DESKTOP_POD_HEIGHT = 226; 55 var DESKTOP_POD_HEIGHT = 226;
56 var POD_ROW_PADDING = 10; 56 var POD_ROW_PADDING = 10;
57 var DESKTOP_ROW_PADDING = 15; 57 var DESKTOP_ROW_PADDING = 15;
58 var CUSTOM_ICON_CONTAINER_SIZE = 40;
58 59
59 /** 60 /**
60 * Minimal padding between user pod and virtual keyboard. 61 * Minimal padding between user pod and virtual keyboard.
61 * @type {number} 62 * @type {number}
62 * @const 63 * @const
63 */ 64 */
64 var USER_POD_KEYBOARD_MIN_PADDING = 20; 65 var USER_POD_KEYBOARD_MIN_PADDING = 20;
65 66
66 /** 67 /**
67 * Maximum time for which the pod row remains hidden until all user images 68 * Maximum time for which the pod row remains hidden until all user images
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 * Stops event propagation from the any user pod child element. 153 * Stops event propagation from the any user pod child element.
153 * @param {Event} e Event to handle. 154 * @param {Event} e Event to handle.
154 */ 155 */
155 function stopEventPropagation(e) { 156 function stopEventPropagation(e) {
156 // Prevent default so that we don't trigger a 'focus' event. 157 // Prevent default so that we don't trigger a 'focus' event.
157 e.preventDefault(); 158 e.preventDefault();
158 e.stopPropagation(); 159 e.stopPropagation();
159 } 160 }
160 161
161 /** 162 /**
163 * Creates an element for custom icon shown in a user pod next to the input
164 * field.
165 * @constructor
166 * @extends {HTMLDivElement}
167 */
168 var UserPodCustomIcon = cr.ui.define(function() {
169 var node = document.createElement('div');
170 node.classList.add('custom-icon-container');
171 node.hidden = true;
172
173 // Create the actual icon element and add it as a child to the container.
174 var iconNode = document.createElement('div');
175 iconNode.classList.add('custom-icon');
176 node.appendChild(iconNode);
177 return node;
178 });
179
180 UserPodCustomIcon.prototype = {
181 __proto__: HTMLDivElement.prototype,
182
183 /**
184 * The icon height.
185 * @type {number}
186 * @private
187 */
188 height_: 0,
189
190 /**
191 * The icon width.
192 * @type {number}
193 * @private
194 */
195 width_: 0,
196
197 /**
198 * Tooltip to be shown when the user hovers over the icon. The icon
199 * properties may be set so the tooltip is shown automatically when the icon
200 * is updated. The tooltip is shown in a bubble attached to the icon
201 * element.
202 * @type {string}
203 * @private
204 */
205 tooltip_: '',
206
207 /**
208 * Whether the tooltip is shown and the user is hovering over the icon.
209 * @type {boolean}
210 * @private
211 */
212 tooltipActive_: false,
213
214 /**
215 * Whether the icon has been shown as a result of |autoshow| parameter begin
216 * set rather than user hovering over the icon.
217 * If this is set, the tooltip will not be removed when the mouse leaves the
218 * icon.
219 * @type {boolean}
220 * @private
221 */
222 tooltipAutoshown_: false,
223
224 /**
225 * A reference to the timeout for showing tooltip after mouse enters the
226 * icon.
227 * @type {?number}
228 * @private
229 */
230 showTooltipTimeout_: null,
231
232 /**
233 * If animation is set, the current horizontal background offset for the
234 * icon resource.
235 * @type {number}
236 * @private
237 */
238 lastAnimationOffset_: 0,
239
240 /**
241 * The reference to interval for progressing the animation.
242 * @type {?number}
243 * @private
244 */
245 animationInterval_: null,
246
247 /**
248 * The width of the resource that contains representations for different
249 * animation stages.
250 * @type {number}
251 * @private
252 */
253 animationResourceSize_: 0,
254
255 /** @override */
256 decorate: function() {
257 this.iconElement.addEventListener('mouseover',
258 this.showTooltipSoon_.bind(this));
259 this.iconElement.addEventListener('mouseout',
260 this.hideTooltip_.bind(this, false));
261 this.iconElement.addEventListener('mousedown',
262 this.hideTooltip_.bind(this, false));
263 },
264
265 /**
266 * Getter for the icon element's div.
267 * @return {HTMLDivElement}
268 */
269 get iconElement() {
270 return this.querySelector('.custom-icon');
271 },
272
273 /**
274 * Set the icon's background image as image set with different
275 * representations for available screen scale factors.
276 * @param {!{scale1x: string, scale2x: string}} icon The icon
277 * representations.
278 */
279 setIconAsImageSet: function(icon) {
280 this.iconElement.style.backgroundImage =
281 '-webkit-image-set(' +
282 'url(' + icon.scale1x + ') 1x,' +
283 'url(' + icon.scale2x + ') 2x)';
284 },
285
286 /**
287 * Sets the icon background image to a chrome://theme URL.
288 * @param {!string} iconUrl The icon's background image URL.
289 */
290 setIconAsResourceUrl: function(iconUrl) {
291 this.iconElement.style.backgroundImage =
292 '-webkit-image-set(' +
293 'url(' + iconUrl + '@1x) 1x,' +
294 'url(' + iconUrl + '@2x) 2x)';
295 },
296
297 /**
298 * Shows the icon.
299 */
300 show: function() {
301 this.hidden = false;
302 },
303
304 /**
305 * Hides the icon. Makes sure the tooltip is hidden and animation reset.
306 */
307 hide: function() {
308 this.hideTooltip_(true);
309 this.setAnimation(null);
310 this.hidden = true;
311 },
312
313 /**
314 * Sets the icon size element size.
315 * @param {!{width: number, height: number}} size The icon size.
316 */
317 setSize: function(size) {
318 this.height_ = size.height < CUSTOM_ICON_CONTAINER_SIZE ?
319 size.height : CUSTOM_ICON_COTAINER_SIZE;
320 this.iconElement.style.height = this.height_ + 'px';
321
322 this.width_ = size.width < CUSTOM_ICON_CONTAINER_SIZE ?
323 size.width : CUSTOM_ICON_COTAINER_SIZE;
324 this.iconElement.style.width = this.width_ + 'px';
325 this.style.width = this.width_ + 'px';
326 },
327
328 /**
329 * Sets the icon opacity.
330 * @param {number} opacity The icon opacity in [0-100] scale.
331 */
332 setOpacity: function(opacity) {
333 if (opacity > 100) {
334 this.style.opacity = 1;
335 } else if (opacity < 0) {
336 this.style.opacity = 0;
337 } else {
338 this.style.opacity = opacity / 100;
339 }
340 },
341
342 /**
343 * Updates the icon tooltip. If {@code autoshow} parameter is set the
344 * tooltip is immediatelly shown. If tooltip text is not set, the method
345 * ensures the tooltip gets hidden. If tooltip is shown prior to this call,
346 * it remains shown, but the tooltip text is updated.
347 * @param {!{text: string, autoshow: boolean}} tooltip The tooltip
348 * parameters.
349 */
350 setTooltip: function(tooltip) {
351 if (this.tooltip_ == tooltip.text && !tooltip.autoshow)
352 return;
353 this.tooltip_ = tooltip.text;
354
355 // If tooltip is already shown, just update the text.
356 if (tooltip.text && this.tooltipActive_ && !$('bubble').hidden) {
357 // If both previous and the new tooltip are supposed to be shown
358 // automatically, keep the autoshown flag.
359 var markAutoshown = this.tooltipAutoshown_ && tooltip.autoshow;
360 this.hideTooltip_(true);
361 this.showTooltip_();
362 this.tooltipAutoshown_ = markAutoshown;
363 return;
364 }
365
366 // If autoshow flag is set, make sure the tooltip gets shown.
367 if (tooltip.text && tooltip.autoshow) {
368 this.hideTooltip_(true);
369 this.showTooltip_();
370 this.tooltipAutoshown_ = true;
371 // Reset the tooltip active flag, which gets set in |showTooltip_|.
372 this.tooltipActive_ = false;
373 return;
374 }
375
376 this.hideTooltip_(true);
377
378 if (this.tooltip_)
379 this.iconElement.setAttribute('aria-lablel', this.tooltip_);
380 },
381
382 /**
383 * Sets the icon animation parameter and starts the animation.
384 * The animation is set using the resource containing all animation frames
385 * concatenated horizontally. The animator offsets the background image in
386 * regural intervals.
387 * @param {?{resourceWidth: number, frameLengthMs: number}} animation
388 * |resourceWidth|: Total width for the resource containing the
389 * animation frames.
390 * |frameLengthMs|: Time interval for which a single animation frame is
391 * shown.
392 */
393 setAnimation: function(animation) {
394 if (this.animationInterval_)
395 clearInterval(this.animationInterval_);
396 this.iconElement.style.backgroundPosition = 'center';
397 if (!animation)
398 return;
399 this.lastAnimationOffset_ = 0;
400 this.animationResourceSize_ = animation.resourceWidth;
401 this.animationInterval_ = setInterval(this.progressAnimation_.bind(this),
402 animation.frameLengthMs);
403 },
404
405 /**
406 * Called when mouse enters the icon. It sets timeout for showing the
407 * tooltip.
408 * @private
409 */
410 showTooltipSoon_: function() {
411 if (this.showTooltipTimeout_ || this.tooltipActive_)
412 return;
413 this.showTooltipTimeout_ =
414 setTimeout(this.showTooltip_.bind(this), 1000);
415 },
416
417 /**
418 * Shows the current tooltip, if one is set.
419 * @private
420 */
421 showTooltip_: function() {
422 if (this.hidden || !this.tooltip_ || this.tooltipActive_)
423 return;
424
425 // If autoshown bubble got hidden, clear the autoshown flag.
426 if ($('bubble').hidden && this.tooltipAutoshown_)
427 this.tooltipAutoshown_ = false;
428
429 // Show the tooltip bubble.
430 var bubbleContent = document.createElement('div');
431 bubbleContent.textContent = this.tooltip_;
432
433 /** @const */ var BUBBLE_OFFSET = CUSTOM_ICON_CONTAINER_SIZE / 2;
434 /** @const */ var BUBBLE_PADDING = 8;
435 $('bubble').showContentForElement(this,
436 cr.ui.Bubble.Attachment.RIGHT,
437 bubbleContent,
438 BUBBLE_OFFSET,
439 BUBBLE_PADDING);
440 this.ensureTooltipTimeoutCleared_();
441 this.tooltipActive_ = true;
442 },
443
444 /**
445 * Hides the tooltip. If the current tooltip was automatically shown, it
446 * will be hidden only if |force| is set.
447 * @param {boolean} Whether the tooltip should be hidden if it got shown
448 * because autoshow flag was set.
449 * @private
450 */
451 hideTooltip_: function(force) {
452 this.tooltipActive_ = false;
453 this.ensureTooltipTimeoutCleared_();
454 if (!force && this.tooltipAutoshown_)
455 return;
456 $('bubble').hideForElement(this);
457 this.tooltipAutoshown_ = false;
458 this.iconElement.removeAttribute('aria-label');
459 },
460
461 /**
462 * Clears timaout for showing the tooltip if it's set.
463 * @private
464 */
465 ensureTooltipTimeoutCleared_: function() {
466 if (this.showTooltipTimeout_) {
467 clearTimeout(this.showTooltipTimeout_);
468 this.showTooltipTimeout_ = null;
469 }
470 },
471
472 /**
473 * Horizontally offsets the animated icon's background for a single icon
474 * size width.
475 * @private
476 */
477 progressAnimation_: function() {
478 this.lastAnimationOffset_ += this.width_;
479 if (this.lastAnimationOffset_ >= this.animationResourceSize_)
480 this.lastAnimationOffset_ = 0;
481 this.iconElement.style.backgroundPosition =
482 '-' + this.lastAnimationOffset_ + 'px center';
483 }
484 };
485
486 /**
162 * Unique salt added to user image URLs to prevent caching. Dictionary with 487 * Unique salt added to user image URLs to prevent caching. Dictionary with
163 * user names as keys. 488 * user names as keys.
164 * @type {Object} 489 * @type {Object}
165 */ 490 */
166 UserPod.userImageSalt_ = {}; 491 UserPod.userImageSalt_ = {};
167 492
168 UserPod.prototype = { 493 UserPod.prototype = {
169 __proto__: HTMLDivElement.prototype, 494 __proto__: HTMLDivElement.prototype,
170 495
171 /** @override */ 496 /** @override */
(...skipping 19 matching lines...) Expand all
191 this.actionBoxMenuRemoveElement.addEventListener('keydown', 516 this.actionBoxMenuRemoveElement.addEventListener('keydown',
192 this.handleRemoveCommandKeyDown_.bind(this)); 517 this.handleRemoveCommandKeyDown_.bind(this));
193 this.actionBoxMenuRemoveElement.addEventListener('blur', 518 this.actionBoxMenuRemoveElement.addEventListener('blur',
194 this.handleRemoveCommandBlur_.bind(this)); 519 this.handleRemoveCommandBlur_.bind(this));
195 this.actionBoxRemoveUserWarningButtonElement.addEventListener( 520 this.actionBoxRemoveUserWarningButtonElement.addEventListener(
196 'click', 521 'click',
197 this.handleRemoveUserConfirmationClick_.bind(this)); 522 this.handleRemoveUserConfirmationClick_.bind(this));
198 this.actionBoxRemoveUserWarningButtonElement.addEventListener( 523 this.actionBoxRemoveUserWarningButtonElement.addEventListener(
199 'keydown', 524 'keydown',
200 this.handleRemoveUserConfirmationKeyDown_.bind(this)); 525 this.handleRemoveUserConfirmationKeyDown_.bind(this));
526
527 var customIcon = this.customIconElement;
528 customIcon.parentNode.replaceChild(new UserPodCustomIcon(), customIcon);
201 }, 529 },
202 530
203 /** 531 /**
204 * Initializes the pod after its properties set and added to a pod row. 532 * Initializes the pod after its properties set and added to a pod row.
205 */ 533 */
206 initialize: function() { 534 initialize: function() {
207 this.passwordElement.addEventListener('keydown', 535 this.passwordElement.addEventListener('keydown',
208 this.parentNode.handleKeyDown.bind(this.parentNode)); 536 this.parentNode.handleKeyDown.bind(this.parentNode));
209 this.passwordElement.addEventListener('keypress', 537 this.passwordElement.addEventListener('keypress',
210 this.handlePasswordKeyPress_.bind(this)); 538 this.handlePasswordKeyPress_.bind(this));
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 get actionBoxRemoveUserWarningButtonElement() { 766 get actionBoxRemoveUserWarningButtonElement() {
439 return this.querySelector('.remove-warning-button'); 767 return this.querySelector('.remove-warning-button');
440 }, 768 },
441 769
442 /** 770 /**
443 * Gets the custom icon. This icon is normally hidden, but can be shown 771 * Gets the custom icon. This icon is normally hidden, but can be shown
444 * using the chrome.screenlockPrivate API. 772 * using the chrome.screenlockPrivate API.
445 * @type {!HTMLDivElement} 773 * @type {!HTMLDivElement}
446 */ 774 */
447 get customIconElement() { 775 get customIconElement() {
448 return this.querySelector('.custom-icon'); 776 return this.querySelector('.custom-icon-container');
449 }, 777 },
450 778
451 /** 779 /**
452 * Updates the user pod element. 780 * Updates the user pod element.
453 */ 781 */
454 update: function() { 782 update: function() {
455 this.imageElement.src = 'chrome://userimage/' + this.user.username + 783 this.imageElement.src = 'chrome://userimage/' + this.user.username +
456 '?id=' + UserPod.userImageSalt_[this.user.username]; 784 '?id=' + UserPod.userImageSalt_[this.user.username];
457 785
458 this.nameElement.textContent = this.user_.displayName; 786 this.nameElement.textContent = this.user_.displayName;
(...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 if (this.shouldShowApps_ == shouldShowApps) 2164 if (this.shouldShowApps_ == shouldShowApps)
1837 return; 2165 return;
1838 2166
1839 this.shouldShowApps_ = shouldShowApps; 2167 this.shouldShowApps_ = shouldShowApps;
1840 this.rebuildPods(); 2168 this.rebuildPods();
1841 }, 2169 },
1842 2170
1843 /** 2171 /**
1844 * Shows a custom icon on a user pod besides the input field. 2172 * Shows a custom icon on a user pod besides the input field.
1845 * @param {string} username Username of pod to add button 2173 * @param {string} username Username of pod to add button
1846 * @param {{scale1x: string, scale2x: string}} icon Dictionary of URLs of 2174 * @param {!{resourceUrl: (string | undefined),
1847 * the custom icon's representations for 1x and 2x scale factors. 2175 * data: ({scale1x: string, scale2x: string} | undefined),
2176 * size: ({width: number, height: number} | undefined),
2177 * animation: ({resourceWidth: number, frameLength: number} |
2178 * undefined),
2179 * opacity: (number | undefined),
2180 * tooltip: ({text: string, autoshow: boolean} | undefined)}} icon
2181 * The icon parameters.
1848 */ 2182 */
1849 showUserPodCustomIcon: function(username, icon) { 2183 showUserPodCustomIcon: function(username, icon) {
1850 var pod = this.getPodWithUsername_(username); 2184 var pod = this.getPodWithUsername_(username);
1851 if (pod == null) { 2185 if (pod == null) {
1852 console.error('Unable to show user pod button for ' + username + 2186 console.error('Unable to show user pod button for ' + username +
1853 ': user pod not found.'); 2187 ': user pod not found.');
1854 return; 2188 return;
1855 } 2189 }
1856 2190
1857 pod.customIconElement.hidden = false; 2191 if (icon.resourceUrl) {
1858 pod.customIconElement.style.backgroundImage = 2192 pod.customIconElement.setIconAsResourceUrl(icon.resourceUrl);
1859 '-webkit-image-set(' + 2193 } else if (icon.data) {
1860 'url(' + icon.scale1x + ') 1x,' + 2194 pod.customIconElement.setIconAsImageSet(icon.data);
1861 'url(' + icon.scale2x + ') 2x)'; 2195 } else {
2196 return;
2197 }
2198
2199 pod.customIconElement.setSize(icon.size || {width: 0, height: 0});
2200 pod.customIconElement.setAnimation(icon.animation || null);
2201 pod.customIconElement.setOpacity(icon.opacity || 100);
2202 pod.customIconElement.show();
2203 // This has to be called after |show| in case the tooltip should be shown
2204 // immediatelly.
2205 pod.customIconElement.setTooltip(
2206 icon.tooltip || {text: '', autoshow: false});
1862 }, 2207 },
1863 2208
1864 /** 2209 /**
1865 * Hides the custom icon in the user pod added by showUserPodCustomIcon(). 2210 * Hides the custom icon in the user pod added by showUserPodCustomIcon().
1866 * @param {string} username Username of pod to remove button 2211 * @param {string} username Username of pod to remove button
1867 */ 2212 */
1868 hideUserPodCustomIcon: function(username) { 2213 hideUserPodCustomIcon: function(username) {
1869 var pod = this.getPodWithUsername_(username); 2214 var pod = this.getPodWithUsername_(username);
1870 if (pod == null) { 2215 if (pod == null) {
1871 console.error('Unable to hide user pod button for ' + username + 2216 console.error('Unable to hide user pod button for ' + username +
1872 ': user pod not found.'); 2217 ': user pod not found.');
1873 return; 2218 return;
1874 } 2219 }
1875 2220
1876 pod.customIconElement.hidden = true; 2221 pod.customIconElement.hide();
1877 }, 2222 },
1878 2223
1879 /** 2224 /**
1880 * Sets the authentication type used to authenticate the user. 2225 * Sets the authentication type used to authenticate the user.
1881 * @param {string} username Username of selected user 2226 * @param {string} username Username of selected user
1882 * @param {number} authType Authentication type, must be one of the 2227 * @param {number} authType Authentication type, must be one of the
1883 * values listed in AUTH_TYPE enum. 2228 * values listed in AUTH_TYPE enum.
1884 * @param {string} value The initial value to use for authentication. 2229 * @param {string} value The initial value to use for authentication.
1885 */ 2230 */
1886 setAuthType: function(username, authType, value) { 2231 setAuthType: function(username, authType, value) {
1887 var pod = this.getPodWithUsername_(username); 2232 var pod = this.getPodWithUsername_(username);
1888 if (pod == null) { 2233 if (pod == null) {
1889 console.error('Unable to set auth type for ' + username + 2234 console.error('Unable to set auth type for ' + username +
1890 ': user pod not found.'); 2235 ': user pod not found.');
1891 return; 2236 return;
1892 } 2237 }
1893 pod.setAuthType(authType, value); 2238 pod.setAuthType(authType, value);
1894 }, 2239 },
1895 2240
1896 /** 2241 /**
1897 * Shows a tooltip bubble explaining Easy Unlock for the focused pod.
1898 */
1899 showEasyUnlockBubble: function() {
1900 if (!this.focusedPod_) {
1901 console.error('No focused pod to show Easy Unlock bubble.');
1902 return;
1903 }
1904
1905 var bubbleContent = document.createElement('div');
1906 bubbleContent.classList.add('easy-unlock-button-content');
1907 bubbleContent.textContent = loadTimeData.getString('easyUnlockTooltip');
1908
1909 var attachElement = this.focusedPod_.customIconElement;
1910 /** @const */ var BUBBLE_OFFSET = 20;
1911 /** @const */ var BUBBLE_PADDING = 8;
1912 $('bubble').showContentForElement(attachElement,
1913 cr.ui.Bubble.Attachment.RIGHT,
1914 bubbleContent,
1915 BUBBLE_OFFSET,
1916 BUBBLE_PADDING);
1917 },
1918
1919 /**
1920 * Updates the display name shown on a public session pod. 2242 * Updates the display name shown on a public session pod.
1921 * @param {string} userID The user ID of the public session 2243 * @param {string} userID The user ID of the public session
1922 * @param {string} displayName The new display name 2244 * @param {string} displayName The new display name
1923 */ 2245 */
1924 setPublicSessionDisplayName: function(userID, displayName) { 2246 setPublicSessionDisplayName: function(userID, displayName) {
1925 var pod = this.getPodWithUsername_(userID); 2247 var pod = this.getPodWithUsername_(userID);
1926 if (pod != null) 2248 if (pod != null)
1927 pod.setDisplayName(displayName); 2249 pod.setDisplayName(displayName);
1928 }, 2250 },
1929 2251
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 if (pod && pod.multiProfilesPolicyApplied) { 2856 if (pod && pod.multiProfilesPolicyApplied) {
2535 pod.userTypeBubbleElement.classList.remove('bubble-shown'); 2857 pod.userTypeBubbleElement.classList.remove('bubble-shown');
2536 } 2858 }
2537 } 2859 }
2538 }; 2860 };
2539 2861
2540 return { 2862 return {
2541 PodRow: PodRow 2863 PodRow: PodRow
2542 }; 2864 };
2543 }); 2865 });
OLDNEW
« no previous file with comments | « ui/login/account_picker/user_pod_row.css ('k') | ui/login/account_picker/user_pod_template.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698