accounts_user_list.js revision 5821806d5e7f356e8fa4b058a389a808ea183019
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    /** @inheritDoc */
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    createItem: function(user) {
40      return new UserListItem(user);
41    },
42
43    /**
44     * Finds the index of user by given username (canonicalized email).
45     * @private
46     * @param {string} username The username to look for.
47     * @return {number} The index of the found user or -1 if not found.
48     */
49    indexOf_: function(username) {
50      var dataModel = this.dataModel;
51      if (!dataModel)
52        return -1;
53
54      var length = dataModel.length;
55      for (var i = 0; i < length; ++i) {
56        var user = dataModel.item(i);
57        if (user.username == username) {
58          return i;
59        }
60      }
61
62      return -1;
63    },
64
65    /**
66     * Update given user's account picture.
67     * @param {string} username User for which to update the image.
68     */
69    updateAccountPicture: function(username) {
70      var index = this.indexOf_(username);
71      if (index >= 0) {
72        var item = this.getListItemByIndex(index);
73        if (item)
74          item.updatePicture();
75      }
76    },
77
78    /**
79     * Loads given user list.
80     * @param {Array.<Object>} users An array of user info objects.
81     * @private
82     */
83    load_: function(users) {
84      this.dataModel = new ArrayDataModel(users);
85    },
86
87    /**
88     * Removes given user from the list.
89     * @param {Object} user User info object to be removed from user list.
90     * @private
91     */
92    removeUser_: function(user) {
93      var e = new Event('remove');
94      e.user = user;
95      this.dispatchEvent(e);
96    }
97  };
98
99  /**
100   * Whether the user list is disabled. Only used for display purpose.
101   * @type {boolean}
102   */
103  cr.defineProperty(UserList, 'disabled', cr.PropertyKind.BOOL_ATTR);
104
105  /**
106   * Creates a new user list item.
107   * @param {Object} user The user account this represents.
108   * @constructor
109   * @extends {cr.ui.ListItem}
110   */
111  function UserListItem(user) {
112    var el = cr.doc.createElement('div');
113    el.user = user;
114    UserListItem.decorate(el);
115    return el;
116  }
117
118  /**
119   * Decorates an element as a user account item.
120   * @param {!HTMLElement} el The element to decorate.
121   */
122  UserListItem.decorate = function(el) {
123    el.__proto__ = UserListItem.prototype;
124    el.decorate();
125  };
126
127  UserListItem.prototype = {
128    __proto__: ListItem.prototype,
129
130    /** @inheritDoc */
131    decorate: function() {
132      ListItem.prototype.decorate.call(this);
133
134      this.className = 'user-list-item';
135
136      this.icon_ = this.ownerDocument.createElement('img');
137      this.icon_.className = 'user-icon';
138      this.updatePicture();
139
140      var labelEmail = this.ownerDocument.createElement('span');
141      labelEmail.className = 'user-email-label';
142      labelEmail.textContent = this.user.email;
143
144      var labelName = this.ownerDocument.createElement('span');
145      labelName.className = 'user-name-label';
146      labelName.textContent = this.user.owner ?
147          loadTimeData.getStringF('username_format', this.user.name) :
148          this.user.name;
149
150      var emailNameBlock = this.ownerDocument.createElement('div');
151      emailNameBlock.className = 'user-email-name-block';
152      emailNameBlock.appendChild(labelEmail);
153      emailNameBlock.appendChild(labelName);
154      emailNameBlock.title = this.user.owner ?
155          loadTimeData.getStringF('username_format', this.user.email) :
156          this.user.email;
157
158      this.appendChild(this.icon_);
159      this.appendChild(emailNameBlock);
160
161      if (!this.user.owner) {
162        var removeButton = this.ownerDocument.createElement('button');
163        removeButton.className =
164            'raw-button remove-user-button custom-appearance';
165        removeButton.addEventListener(
166            'click', this.handleRemoveButtonClick_.bind(this));
167        this.appendChild(removeButton);
168      }
169    },
170
171    /**
172     * Handles click on the remove button.
173     * @param {Event} e Click event.
174     * @private
175     */
176    handleRemoveButtonClick_: function(e) {
177      // Handle left button click
178      if (e.button == 0)
179        this.parentNode.removeUser_(this.user);
180    },
181
182    /**
183     * Reloads user picture.
184     */
185    updatePicture: function() {
186      this.icon_.src = 'chrome://userimage/' + this.user.username +
187                       '?id=' + (new Date()).getTime();
188    }
189  };
190
191  return {
192    UserList: UserList
193  };
194});
195