1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5cr.define('options.accounts', function() { 6 /** @const */ var List = cr.ui.List; 7 /** @const */ var ListItem = cr.ui.ListItem; 8 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; 9 10 /** 11 * Creates a new user list. 12 * @param {Object=} opt_propertyBag Optional properties. 13 * @constructor 14 * @extends {cr.ui.List} 15 */ 16 var UserList = cr.ui.define('list'); 17 18 UserList.prototype = { 19 __proto__: List.prototype, 20 21 pref: 'cros.accounts.users', 22 23 /** @override */ 24 decorate: function() { 25 List.prototype.decorate.call(this); 26 27 // HACK(arv): http://crbug.com/40902 28 window.addEventListener('resize', this.redraw.bind(this)); 29 30 var self = this; 31 32 // Listens to pref changes. 33 Preferences.getInstance().addEventListener(this.pref, 34 function(event) { 35 self.load_(event.value.value); 36 }); 37 }, 38 39 /** 40 * @override 41 * @param {Object} user 42 */ 43 createItem: function(user) { 44 return new UserListItem(user); 45 }, 46 47 /** 48 * Finds the index of user by given username (canonicalized email). 49 * @private 50 * @param {string} username The username to look for. 51 * @return {number} The index of the found user or -1 if not found. 52 */ 53 indexOf_: function(username) { 54 var dataModel = this.dataModel; 55 if (!dataModel) 56 return -1; 57 58 var length = dataModel.length; 59 for (var i = 0; i < length; ++i) { 60 var user = dataModel.item(i); 61 if (user.username == username) { 62 return i; 63 } 64 } 65 66 return -1; 67 }, 68 69 /** 70 * Update given user's account picture. 71 * @param {string} username User for which to update the image. 72 */ 73 updateAccountPicture: function(username) { 74 var index = this.indexOf_(username); 75 if (index >= 0) { 76 var item = this.getListItemByIndex(index); 77 if (item) 78 item.updatePicture(); 79 } 80 }, 81 82 /** 83 * Loads given user list. 84 * @param {!Array.<Object>} users An array of user info objects. 85 * @private 86 */ 87 load_: function(users) { 88 this.dataModel = new ArrayDataModel(users); 89 }, 90 91 /** 92 * Removes given user from the list. 93 * @param {Object} user User info object to be removed from user list. 94 * @private 95 */ 96 removeUser_: function(user) { 97 var e = new Event('remove'); 98 e.user = user; 99 this.dispatchEvent(e); 100 } 101 }; 102 103 /** 104 * Whether the user list is disabled. Only used for display purpose. 105 */ 106 cr.defineProperty(UserList, 'disabled', cr.PropertyKind.BOOL_ATTR); 107 108 /** 109 * Creates a new user list item. 110 * @param {Object} user The user account this represents. 111 * @constructor 112 * @extends {cr.ui.ListItem} 113 */ 114 function UserListItem(user) { 115 var el = cr.doc.createElement('div'); 116 el.user = user; 117 UserListItem.decorate(el); 118 return el; 119 } 120 121 /** 122 * Decorates an element as a user account item. 123 * @param {!HTMLElement} el The element to decorate. 124 */ 125 UserListItem.decorate = function(el) { 126 el.__proto__ = UserListItem.prototype; 127 el.decorate(); 128 }; 129 130 UserListItem.prototype = { 131 __proto__: ListItem.prototype, 132 133 /** @override */ 134 decorate: function() { 135 ListItem.prototype.decorate.call(this); 136 137 this.className = 'user-list-item'; 138 139 this.icon_ = this.ownerDocument.createElement('img'); 140 this.icon_.className = 'user-icon'; 141 this.updatePicture(); 142 143 var labelEmail = this.ownerDocument.createElement('span'); 144 labelEmail.className = 'user-email-label'; 145 labelEmail.textContent = this.user.email; 146 147 var labelName = this.ownerDocument.createElement('span'); 148 labelName.className = 'user-name-label'; 149 labelName.textContent = this.user.owner ? 150 loadTimeData.getStringF('username_format', this.user.name) : 151 this.user.name; 152 153 var emailNameBlock = this.ownerDocument.createElement('div'); 154 emailNameBlock.className = 'user-email-name-block'; 155 emailNameBlock.appendChild(labelEmail); 156 emailNameBlock.appendChild(labelName); 157 emailNameBlock.title = this.user.owner ? 158 loadTimeData.getStringF('username_format', this.user.email) : 159 this.user.email; 160 161 this.appendChild(this.icon_); 162 this.appendChild(emailNameBlock); 163 164 if (!this.user.owner) { 165 var removeButton = this.ownerDocument.createElement('button'); 166 removeButton.className = 167 'raw-button remove-user-button custom-appearance'; 168 removeButton.addEventListener( 169 'click', this.handleRemoveButtonClick_.bind(this)); 170 this.appendChild(removeButton); 171 } 172 }, 173 174 /** 175 * Handles click on the remove button. 176 * @param {Event} e Click event. 177 * @private 178 */ 179 handleRemoveButtonClick_: function(e) { 180 // Handle left button click 181 if (e.button == 0) 182 this.parentNode.removeUser_(this.user); 183 }, 184 185 /** 186 * Reloads user picture. 187 */ 188 updatePicture: function() { 189 this.icon_.src = 'chrome://userimage/' + this.user.username + 190 '?id=' + (new Date()).getTime(); 191 } 192 }; 193 194 return { 195 UserList: UserList 196 }; 197}); 198