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

Side by Side Diff: chrome/browser/resources/chromeos/login/user_pod_row.js

Issue 7461142: [ChromeOS] Assorted WebUI login fixes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comment in #1 Created 9 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 (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // Pod width. 170px Pod + 10px padding + 10px margin on both sides. 10 // Pod width. 170px Pod + 10px padding + 10px margin on both sides.
(...skipping 20 matching lines...) Expand all
31 */ 31 */
32 var UserPod = cr.ui.define(function() { 32 var UserPod = cr.ui.define(function() {
33 return $('user-pod-template').cloneNode(true); 33 return $('user-pod-template').cloneNode(true);
34 }); 34 });
35 35
36 UserPod.prototype = { 36 UserPod.prototype = {
37 __proto__: HTMLDivElement.prototype, 37 __proto__: HTMLDivElement.prototype,
38 38
39 /** @inheritDoc */ 39 /** @inheritDoc */
40 decorate: function() { 40 decorate: function() {
41 this.addEventListener('click', this.handleClick_.bind(this)); 41 // Make this focusable
42 if (!this.hasAttribute('tabindex'))
43 this.tabIndex = 0;
44
45 this.addEventListener('mousedown', this.handleMouseDown_.bind(this));
46
42 this.enterButtonElement.addEventListener('click', 47 this.enterButtonElement.addEventListener('click',
43 this.activate.bind(this)); 48 this.activate.bind(this));
44 this.removeUserButtonElement.addEventListener('click',
45 this.handleRemoveUserClick_.bind(this));
46 }, 49 },
47 50
48 /** 51 /**
49 * Initializes the pod after its properties set and added to a pod row. 52 * Initializes the pod after its properties set and added to a pod row.
50 */ 53 */
51 initialize: function() { 54 initialize: function() {
52 if (!this.isGuest) { 55 if (!this.isGuest) {
53 this.passwordElement.addEventListener('keydown', 56 this.passwordElement.addEventListener('keydown',
54 this.parentNode.handleKeyDown.bind(this.parentNode)); 57 this.parentNode.handleKeyDown.bind(this.parentNode));
55 } 58 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 * @param {boolean} takeFocus True to take focus. 172 * @param {boolean} takeFocus True to take focus.
170 */ 173 */
171 reset: function(takeFocus) { 174 reset: function(takeFocus) {
172 this.passwordElement.value = ''; 175 this.passwordElement.value = '';
173 176
174 if (takeFocus) 177 if (takeFocus)
175 this.mainInput.focus(); 178 this.mainInput.focus();
176 }, 179 },
177 180
178 /** 181 /**
179 * Handles click event on remove user button. 182 * Handles mousedown event.
180 * @private
181 */ 183 */
182 handleRemoveUserClick_: function(e) { 184 handleMouseDown_: function(e) {
183 chrome.send('removeUser', [this.email]); 185 if (e.target == this.removeUserButtonElement) {
184 this.parentNode.removeChild(this); 186 chrome.send('removeUser', [this.user.emailAddress]);
185 },
186 187
187 /** 188 // Prevent default so that we don't trigger 'focus' event.
188 * Handles click event. 189 e.preventDefault();
189 */ 190 }
190 handleClick_: function(e) {
191 this.parentNode.focusPod(this);
192 e.stopPropagation();
193 } 191 }
194 }; 192 };
195 193
196 194
197 /** 195 /**
198 * Creates a new pod row element. 196 * Creates a new pod row element.
199 * @constructor 197 * @constructor
200 * @extends {HTMLDivElement} 198 * @extends {HTMLDivElement}
201 */ 199 */
202 var PodRow = cr.ui.define('podrow'); 200 var PodRow = cr.ui.define('podrow');
203 201
204 PodRow.prototype = { 202 PodRow.prototype = {
205 __proto__: HTMLDivElement.prototype, 203 __proto__: HTMLDivElement.prototype,
206 204
207 // Focused pod. 205 // Focused pod.
208 focusedPod_ : undefined, 206 focusedPod_ : undefined,
209 207
210 // Acitvated pod, i.e. the pod of current login attempt. 208 // Acitvated pod, i.e. the pod of current login attempt.
211 activatedPod_: undefined, 209 activatedPod_: undefined,
212 210
213 /** @inheritDoc */ 211 /** @inheritDoc */
214 decorate: function() { 212 decorate: function() {
215 // Make this focusable 213 this.style.left = 0;
216 if (!this.hasAttribute('tabindex'))
217 this.tabIndex = 0;
218 214
219 this.style.left = 0; 215 this.ownerDocument.addEventListener('focus',
216 this.handleFocus_.bind(this), true);
220 217
221 this.ownerDocument.addEventListener('click', 218 this.ownerDocument.addEventListener('click',
222 this.handleClick_.bind(this)); 219 this.handleClick_.bind(this));
223 this.ownerDocument.addEventListener('keydown', 220 this.ownerDocument.addEventListener('keydown',
224 this.handleKeyDown.bind(this)); 221 this.handleKeyDown.bind(this));
225 }, 222 },
226 223
227 /** 224 /**
228 * Returns all the pods in this pod row. 225 * Returns all the pods in this pod row.
229 */ 226 */
230 get pods() { 227 get pods() {
231 return this.children; 228 return this.children;
232 }, 229 },
233 230
234 /** 231 /**
235 * Creates a user pod from given email. 232 * Creates a user pod from given email.
236 * @param {string} email User's email. 233 * @param {string} email User's email.
237 */ 234 */
238 createUserPod: function(user) { 235 createUserPod: function(user) {
239 var userPod = new UserPod({user: user}); 236 var userPod = new UserPod({user: user});
240 userPod.hidden = false; 237 userPod.hidden = false;
241 return userPod; 238 return userPod;
242 }, 239 },
243 240
244 /** 241 /**
245 * Add an existing user pod to this pod row. 242 * Add an existing user pod to this pod row.
246 * @param {!Object} user User info dictionary. 243 * @param {!Object} user User info dictionary.
244 * @param {boolean} animated Whether to use init animation.
247 */ 245 */
248 addUserPod: function(user) { 246 addUserPod: function(user, animated) {
249 var userPod = this.createUserPod(user); 247 var userPod = this.createUserPod(user);
248 if (animated) {
249 userPod.classList.add('init');
250 userPod.nameElement.classList.add('init');
251 }
252
250 this.appendChild(userPod); 253 this.appendChild(userPod);
251 userPod.initialize(); 254 userPod.initialize();
252 }, 255 },
253 256
254 /** 257 /**
255 * Ensures the given pod is visible. 258 * Ensures the given pod is visible.
256 * @param {UserPod} pod Pod to scroll into view. 259 * @param {UserPod} pod Pod to scroll into view.
257 */ 260 */
258 scrollPodIntoView: function(pod) { 261 scrollPodIntoView: function(pod) {
259 var podIndex = this.findIndex_(pod); 262 var podIndex = this.findIndex_(pod);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 this.pods[i], 'init'); 301 this.pods[i], 'init');
299 window.setTimeout(removeClass, 700 + i * 70, 302 window.setTimeout(removeClass, 700 + i * 70,
300 this.pods[i].nameElement, 'init'); 303 this.pods[i].nameElement, 'init');
301 } 304 }
302 }, 305 },
303 306
304 /** 307 /**
305 * Populates pod row with given existing users and 308 * Populates pod row with given existing users and
306 * kick start init animiation. 309 * kick start init animiation.
307 * @param {array} users Array of existing user emails. 310 * @param {array} users Array of existing user emails.
311 * @param {boolean} animated Whether to use init animation.
308 */ 312 */
309 loadPods: function(users) { 313 loadPods: function(users, animated) {
310 // Clear existing pods. 314 // Clear existing pods.
311 this.innerHTML = ''; 315 this.innerHTML = '';
312 this.focusedPod_ = undefined; 316 this.focusedPod_ = undefined;
317 this.activatedPod_ = undefined;
313 318
314 // Popoulate the pod row. 319 // Popoulate the pod row.
315 for (var i = 0; i < users.length; ++i) { 320 for (var i = 0; i < users.length; ++i) {
316 this.addUserPod(users[i]); 321 this.addUserPod(users[i], animated);
317 } 322 }
318 }, 323 },
319 324
320 /** 325 /**
321 * Focuses a given user pod or clear focus when given null. 326 * Focuses a given user pod or clear focus when given null.
322 * @param {UserPod} pod User pod to focus or null to clear focus. 327 * @param {UserPod} pod User pod to focus or null to clear focus.
323 */ 328 */
324 focusPod: function(pod) { 329 focusPod: function(pod) {
325 for (var i = 0; i < this.pods.length; ++i) { 330 if (this.focusedPod_ == pod)
326 this.pods[i].classList.remove('focused'); 331 return;
327 this.pods[i].classList.add('faded');
328 }
329 332
330 if (pod) { 333 if (pod) {
331 if (pod.isGuest || 334 if (pod.isGuest ||
332 localStrings.getString('authType') != 'ext' || 335 localStrings.getString('authType') != 'ext' ||
333 pod.user.oauthTokenStatus == OAUTH_TOKEN_STATUS_VALID) { 336 pod.user.oauthTokenStatus == OAUTH_TOKEN_STATUS_VALID) {
334 // Focus current pod if it is guest pod, or 337 // Focus current pod if it is guest pod, or
335 // we are not using gaia ext for signin or 338 // we are not using gaia ext for signin or
336 // the user has a valid oauth token. 339 // the user has a valid oauth token.
337 pod.classList.remove("faded"); 340 for (var i = 0; i < this.pods.length; ++i) {
338 pod.classList.add("focused"); 341 if (this.pods[i] == pod) {
342 pod.classList.remove("faded");
343 pod.classList.add("focused");
344 } else {
345 this.pods[i].classList.remove('focused');
346 this.pods[i].classList.add('faded');
347 }
348 }
339 pod.focusInput(); 349 pod.focusInput();
340 350
341 this.focusedPod_ = pod; 351 this.focusedPod_ = pod;
342 this.scrollPodIntoView(pod); 352 this.scrollPodIntoView(pod);
343 } else { 353 } else {
344 // Otherwise, switch to Gaia signin. 354 // Otherwise, switch to Gaia signin.
345 Oobe.showSigninUI(pod.user.emailAddress); 355 Oobe.showSigninUI(pod.user.emailAddress);
356 this.focusPod(); // Clears current focus.
346 } 357 }
347 } else { 358 } else {
348 for (var i = 0; i < this.pods.length; ++i) { 359 for (var i = 0; i < this.pods.length; ++i) {
360 this.pods[i].classList.remove('focused');
349 this.pods[i].classList.remove('faded'); 361 this.pods[i].classList.remove('faded');
350 } 362 }
351 this.focusedPod_ = undefined; 363 this.focusedPod_ = undefined;
352 } 364 }
353
354 // TODO(xiyuan): Put this in a proper place.
355 $('bubble').hide();
356 }, 365 },
357 366
358 /** 367 /**
359 * Returns the currently activated pod. 368 * Returns the currently activated pod.
360 */ 369 */
361 get activated() { 370 get activated() {
362 return this.activatedPod_; 371 return this.activatedPod_;
363 }, 372 },
364 373
365 /** 374 /**
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 415
407 if (this.activatedPod_) 416 if (this.activatedPod_)
408 this.activatedPod_.reset(takeFocus); 417 this.activatedPod_.reset(takeFocus);
409 }, 418 },
410 419
411 /** 420 /**
412 * Handler of click event. 421 * Handler of click event.
413 * @private 422 * @private
414 */ 423 */
415 handleClick_: function(e) { 424 handleClick_: function(e) {
416 // Clears focus. 425 // Clears focus if not clicked on a pod.
417 this.focusPod(); 426 if (e.target.parentNode != this &&
427 e.target.parentNode.parentNode != this)
428 this.focusPod();
418 }, 429 },
419 430
420 /** 431 /**
432 * Handles focus event.
433 */
434 handleFocus_: function(e) {
435 if (e.target.parentNode == this) {
436 // Focus on a pod
437 if (e.target.classList.contains('focused'))
438 e.target.focusInput();
439 else
440 this.focusPod(e.target);
441 } else if (e.target.parentNode.parentNode != this) {
442 // Clears pod focus when we reach here. It means new focus is neither
443 // on a pod nor on a button/input for a pod.
444 this.focusPod();
445 }
446 },
447
448 /**
421 * Handler of keydown event. 449 * Handler of keydown event.
422 * @public 450 * @public
423 */ 451 */
424 handleKeyDown: function(e) { 452 handleKeyDown: function(e) {
425 var editing = false; 453 var editing = false;
426 if (e.target.tagName == 'INPUT' && e.target.value) 454 if (e.target.tagName == 'INPUT' && e.target.value)
427 editing = true; 455 editing = true;
428 456
429 // TODO(xiyuan): Put this in a proper place.
430 $('bubble').hide();
431
432 switch (e.keyIdentifier) { 457 switch (e.keyIdentifier) {
433 case 'Left': 458 case 'Left':
434 if (!editing) { 459 if (!editing) {
435 if (this.focusedPod_ && this.focusedPod_.previousElementSibling) 460 if (this.focusedPod_ && this.focusedPod_.previousElementSibling)
436 this.focusPod(this.focusedPod_.previousElementSibling); 461 this.focusPod(this.focusedPod_.previousElementSibling);
437 else 462 else
438 this.focusPod(this.lastElementChild); 463 this.focusPod(this.lastElementChild);
439 464
440 e.stopPropagation(); 465 e.stopPropagation();
441 } 466 }
442 break; 467 break;
443 case 'Right': 468 case 'Right':
444 if (!editing) { 469 if (!editing) {
445 if (this.focusedPod_ && this.focusedPod_.nextElementSibling) 470 if (this.focusedPod_ && this.focusedPod_.nextElementSibling)
446 this.focusPod(this.focusedPod_.nextElementSibling); 471 this.focusPod(this.focusedPod_.nextElementSibling);
447 else 472 else
448 this.focusPod(this.firstElementChild); 473 this.focusPod(this.firstElementChild);
449 474
450 e.stopPropagation(); 475 e.stopPropagation();
451 } 476 }
452 break; 477 break;
453 case 'Enter': 478 case 'Enter':
454 this.activatePod(this.focusedPod_); 479 if (this.focusedPod_) {
455 e.stopPropagation(); 480 this.activatePod(this.focusedPod_);
481 e.stopPropagation();
482 }
456 break; 483 break;
457 } 484 }
458 } 485 }
459 }; 486 };
460 487
461 return { 488 return {
462 PodRow: PodRow 489 PodRow: PodRow
463 }; 490 };
464 }); 491 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698