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

Side by Side Diff: chrome/browser/resources/options/password_manager_list.js

Issue 5935003: DOMUI: Implement new-style password manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review fixes. Created 10 years 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 cr.define('options.passwordManager', function() { 5 cr.define('options.passwordManager', function() {
6 6 const ArrayDataModel = cr.ui.ArrayDataModel;
7 const DeletableItemList = options.DeletableItemList;
7 const List = cr.ui.List; 8 const List = cr.ui.List;
8 const ListItem = cr.ui.ListItem; 9 const ListItem = cr.ui.ListItem;
9 const ArrayDataModel = cr.ui.ArrayDataModel;
10 10
11 /** 11 /**
12 * Creates a new passwords list item. 12 * Creates a new passwords list item.
13 * @param {Array} entry A pair of the form [url, username]. 13 * @param {Array} entry An array of the form [url, username, password].
14 * @constructor 14 * @constructor
15 * @extends {cr.ui.ListItem} 15 * @extends {cr.ui.ListItem}
16 */ 16 */
17 function PasswordsListItem(entry) { 17 function PasswordListItem(entry) {
18 var el = cr.doc.createElement('li'); 18 var el = cr.doc.createElement('div');
19 el.dataItem = entry; 19 el.dataItem = entry;
20 el.__proto__ = PasswordsListItem.prototype; 20 el.__proto__ = PasswordListItem.prototype;
21 el.decorate(); 21 el.decorate();
22 22
23 return el; 23 return el;
24 } 24 }
25 25
26 PasswordsListItem.prototype = { 26 PasswordListItem.prototype = {
27 __proto__: ListItem.prototype, 27 __proto__: ListItem.prototype,
28 28
29 /** 29 /** @inheritDoc */
30 * Call when an element is decorated as a list item.
31 */
32 decorate: function() { 30 decorate: function() {
33 ListItem.prototype.decorate.call(this); 31 ListItem.prototype.decorate.call(this);
34 32
35 // Labels for display 33 // The URL of the site.
36 var urlLabel = cr.doc.createElement('span'); 34 var urlLabel = this.ownerDocument.createElement('div');
35 urlLabel.className = 'url';
36 urlLabel.classList.add('favicon-cell');
37 urlLabel.textContent = this.url; 37 urlLabel.textContent = this.url;
38 urlLabel.style.backgroundImage = url('chrome://favicon/' + this.url);
38 this.appendChild(urlLabel); 39 this.appendChild(urlLabel);
39 this.urlLabel = urlLabel;
40 40
41 var usernameLabel = cr.doc.createElement('span'); 41 // The stored username.
42 var usernameLabel = this.ownerDocument.createElement('div');
43 usernameLabel.className = 'name';
42 usernameLabel.textContent = this.username; 44 usernameLabel.textContent = this.username;
43 usernameLabel.className = 'passwordsUsername';
44 this.appendChild(usernameLabel); 45 this.appendChild(usernameLabel);
45 this.usernameLabel = usernameLabel; 46
47 // The stored password.
48 var passwordInputDiv = this.ownerDocument.createElement('div');
49 passwordInputDiv.className = 'password';
50
51 // The password input field.
52 var passwordInput = this.ownerDocument.createElement('input');
53 passwordInput.className = 'inactive-password';
54 passwordInput.type = 'password';
55 passwordInput.value = this.password;
56 passwordInputDiv.appendChild(passwordInput);
57
58 // The show/hide button.
59 var buttonSpan = this.ownerDocument.createElement('span');
60 buttonSpan.className = 'hidden';
61 buttonSpan.addEventListener('click', this.onClick_, true);
62 passwordInputDiv.appendChild(buttonSpan);
63
64 this.appendChild(passwordInputDiv);
65 },
66
67 /** @inheritDoc */
68 selectionChanged: function() {
69 var passwordInput = this.querySelector('input[type=password]');
70 var buttonSpan = passwordInput.nextSibling;
71 if (this.selected) {
72 passwordInput.classList.remove('inactive-password');
73 buttonSpan.classList.remove('hidden');
74 } else {
75 passwordInput.classList.add('inactive-password');
76 buttonSpan.classList.add('hidden');
77 }
46 }, 78 },
47 79
48 /** 80 /**
49 * Get the url for the entry. 81 * On-click event handler. Swaps the type of the input field from password
82 * to text and back.
83 * @private
84 */
85 onClick_: function(event) {
86 // The password is the input element previous to the button span.
87 var buttonSpan = event.currentTarget;
88 var passwordInput = buttonSpan.previousSibling;
89 var type = passwordInput.type;
90 passwordInput.type = (type == 'password') ? 'text' : 'password';
arv (Not doing code reviews) 2010/12/17 20:07:34 useless parens
James Hawkins 2010/12/17 21:32:40 Done.
91 },
92
93 /**
94 * Get and set the URL for the entry.
50 * @type {string} 95 * @type {string}
51 */ 96 */
52 get url() { 97 get url() {
53 return this.dataItem[0]; 98 return this.dataItem[0];
54 }, 99 },
55 set url(url) { 100 set url(url) {
56 this.dataItem[0] = url; 101 this.dataItem[0] = url;
57 }, 102 },
58 103
59 /** 104 /**
60 * Get the username for the entry. 105 * Get and set the username for the entry.
61 * @type {string} 106 * @type {string}
62 */ 107 */
63 get username() { 108 get username() {
64 return this.dataItem[1]; 109 return this.dataItem[1];
65 }, 110 },
66 set username(username) { 111 set username(username) {
67 this.dataItem[1] = username; 112 this.dataItem[1] = username;
68 }, 113 },
114
115 /**
116 * Get and set the password for the entry.
117 * @type {string}
118 */
119 get password() {
120 return this.dataItem[2];
121 },
122 set password(password) {
123 this.dataItem[2] = password;
124 },
69 }; 125 };
70 126
71 /** 127 /**
72 * Creates a new PasswordExceptions list item. 128 * Creates a new PasswordExceptions list item.
73 * @param {Array} entry A pair of the form [url, username]. 129 * @param {Array} entry A pair of the form [url, username].
74 * @constructor 130 * @constructor
75 * @extends {cr.ui.ListItem} 131 * @extends {cr.ui.ListItem}
76 */ 132 */
77 function PasswordExceptionsListItem(entry) { 133 function PasswordExceptionsListItem(entry) {
78 var el = cr.doc.createElement('li'); 134 var el = cr.doc.createElement('div');
79 el.dataItem = entry; 135 el.dataItem = entry;
80 el.__proto__ = PasswordExceptionsListItem.prototype; 136 el.__proto__ = PasswordExceptionsListItem.prototype;
81 el.decorate(); 137 el.decorate();
82 138
83 return el; 139 return el;
84 } 140 }
85 141
86 PasswordExceptionsListItem.prototype = { 142 PasswordExceptionsListItem.prototype = {
87 __proto__: ListItem.prototype, 143 __proto__: ListItem.prototype,
88 144
89 /** 145 /**
90 * Call when an element is decorated as a list item. 146 * Call when an element is decorated as a list item.
91 */ 147 */
92 decorate: function() { 148 decorate: function() {
93 ListItem.prototype.decorate.call(this); 149 ListItem.prototype.decorate.call(this);
94 150
95 // Labels for display 151 // The URL of the site.
96 var urlLabel = cr.doc.createElement('span'); 152 var urlLabel = this.ownerDocument.createElement('div');
153 urlLabel.className = 'url';
154 urlLabel.classList.add('favicon-cell');
97 urlLabel.textContent = this.url; 155 urlLabel.textContent = this.url;
156 urlLabel.style.backgroundImage = url('chrome://favicon/' + this.url);
98 this.appendChild(urlLabel); 157 this.appendChild(urlLabel);
99 this.urlLabel = urlLabel;
100 }, 158 },
101 159
102 /** 160 /**
103 * Get the url for the entry. 161 * Get the url for the entry.
104 * @type {string} 162 * @type {string}
105 */ 163 */
106 get url() { 164 get url() {
107 return this.dataItem; 165 return this.dataItem;
108 }, 166 },
109 set url(url) { 167 set url(url) {
110 this.dataItem = url; 168 this.dataItem = url;
111 }, 169 },
112 }; 170 };
113 171
114
115 /** 172 /**
116 * Create a new passwords list. 173 * Create a new passwords list.
117 * @constructor 174 * @constructor
118 * @extends {cr.ui.List} 175 * @extends {cr.ui.List}
119 */ 176 */
120 var PasswordsList = cr.ui.define('list'); 177 var PasswordsList = cr.ui.define('list');
121 178
122 PasswordsList.prototype = { 179 PasswordsList.prototype = {
123 __proto__: List.prototype, 180 __proto__: DeletableItemList.prototype,
124 /**
125 * Called when an element is decorated as a list.
126 */
127 decorate: function() {
128 List.prototype.decorate.call(this);
129 181
130 this.dataModel = new ArrayDataModel([]); 182 /** @inheritDoc */
183 createItemContents: function(entry) {
184 return new PasswordListItem(entry);
185 },
186
187 /** @inheritDoc */
188 deleteItemAtIndex: function(index) {
189 PasswordManager.removeSavedPassword(index);
131 }, 190 },
132 191
133 /** 192 /**
134 * Creates an item to go in the list.
135 * @param {Object} entry The element from the data model for this row.
136 */
137 createItem: function(entry) {
138 return new PasswordsListItem(entry);
139 },
140
141 /**
142 * Adds an entry to the js model.
143 * @param {Array} entry A pair of the form [url, username].
144 */
145 addEntry: function(entry) {
146 this.dataModel.push(entry);
147 this.listArea.updateButtonSensitivity();
148 },
149
150 /**
151 * Remove all entries from the js model.
152 */
153 clear: function() {
154 this.dataModel = new ArrayDataModel([]);
155 this.listArea.updateButtonSensitivity();
156 },
157
158 /**
159 * Remove selected row from browser's model.
160 */
161 removeSelectedRow: function() {
162 var selectedIndex = this.selectionModel.selectedIndex;
163 PasswordManager.removeSavedPassword(selectedIndex);
164 },
165
166 showSelectedPassword: function() {
167 var selectedIndex = this.selectionModel.selectedIndex;
168 PasswordManager.showSelectedPassword(selectedIndex);
169 },
170
171 /**
172 * The length of the list. 193 * The length of the list.
173 */ 194 */
174 get length() { 195 get length() {
175 return this.dataModel.length; 196 return this.dataModel.length;
176 }, 197 },
177 }; 198 };
178 199
179 /** 200 /**
180 * Create a new passwords list. 201 * Create a new passwords list.
181 * @constructor 202 * @constructor
182 * @extends {cr.ui.List} 203 * @extends {cr.ui.List}
183 */ 204 */
184 var PasswordExceptionsList = cr.ui.define('list'); 205 var PasswordExceptionsList = cr.ui.define('list');
185 206
186 PasswordExceptionsList.prototype = { 207 PasswordExceptionsList.prototype = {
187 __proto__: List.prototype, 208 __proto__: DeletableItemList.prototype,
188 /**
189 * Called when an element is decorated as a list.
190 */
191 decorate: function() {
192 List.prototype.decorate.call(this);
193 209
194 this.dataModel = new ArrayDataModel([]); 210 /** @inheritDoc */
211 createItemContents: function(entry) {
212 return new PasswordExceptionsListItem(entry);
213 },
214
215 /** @inheritDoc */
216 deleteItemAtIndex: function(index) {
217 PasswordManager.removePasswordException(index);
195 }, 218 },
196 219
197 /** 220 /**
198 * Creates an item to go in the list.
199 * @param {Object} entry The element from the data model for this row.
200 */
201 createItem: function(entry) {
202 return new PasswordExceptionsListItem(entry);
203 },
204
205 /**
206 * Adds an entry to the js model.
207 * @param {Array} entry A pair of the form [url, username].
208 */
209 addEntry: function(entry) {
210 this.dataModel.push(entry);
211 this.listArea.updateButtonSensitivity();
212 },
213
214 /**
215 * Remove all entries from the js model.
216 */
217 clear: function() {
218 this.dataModel = new ArrayDataModel([]);
219 this.listArea.updateButtonSensitivity();
220 },
221
222 /**
223 * Remove selected row from browser's model.
224 */
225 removeSelectedRow: function() {
226 var selectedIndex = this.selectionModel.selectedIndex;
227 PasswordManager.removePasswordException(selectedIndex);
228 },
229
230 /**
231 * The length of the list. 221 * The length of the list.
232 */ 222 */
233 get length() { 223 get length() {
234 return this.dataModel.length; 224 return this.dataModel.length;
235 }, 225 },
236 }; 226 };
237 227
238 /**
239 * Create a new passwords list area.
240 * @constructor
241 * @extends {cr.ui.div}
242 */
243 var PasswordsListArea = cr.ui.define('div');
244
245 PasswordsListArea.prototype = {
246 __proto__: HTMLDivElement.prototype,
247
248 decorate: function() {
249 this.passwordsList = this.querySelector('list');
250 this.passwordsList.listArea = this;
251
252 PasswordsList.decorate(this.passwordsList);
253 this.passwordsList.selectionModel.addEventListener(
254 'change', this.handleOnSelectionChange_.bind(this));
255
256 var removeRow = cr.doc.createElement('button');
257 removeRow.textContent = templateData.passwordsRemoveButton;
258 this.appendChild(removeRow);
259 this.removeRow = removeRow;
260
261 var removeAll = cr.doc.createElement('button');
262 removeAll.textContent = templateData.passwordsRemoveAllButton;
263 this.appendChild(removeAll);
264 this.removeAll = removeAll;
265
266 var showHidePassword = cr.doc.createElement('button');
267 showHidePassword.textContent = templateData.passwordsShowButton;
268 this.appendChild(showHidePassword);
269 this.showHidePassword = showHidePassword;
270 this.showingPassword = false
271
272 var passwordLabel = cr.doc.createElement('span');
273 this.appendChild(passwordLabel);
274 this.passwordLabel = passwordLabel;
275
276 var self = this;
277 removeRow.onclick = function(event) {
278 self.passwordsList.removeSelectedRow();
279 };
280
281 removeAll.onclick = function(event) {
282 AlertOverlay.show(
283 undefined,
284 localStrings.getString('passwordsRemoveAllWarning'),
285 localStrings.getString('yesButtonLabel'),
286 localStrings.getString('noButtonLabel'),
287 function() { PasswordManager.removeAllPasswords(); });
288 };
289
290 showHidePassword.onclick = function(event) {
291 if(self.showingPassword) {
292 self.passwordLabel.textContent = "";
293 this.textContent = templateData.passwordsShowButton;
294 } else {
295 self.passwordsList.showSelectedPassword();
296 this.textContent = templateData.passwordsHideButton;
297 }
298 self.showingPassword = !self.showingPassword;
299 };
300
301 this.updateButtonSensitivity();
302 },
303
304 displayReturnedPassword: function(password) {
305 this.passwordLabel.textContent = password;
306 },
307
308 /**
309 * Update the button's states
310 */
311 updateButtonSensitivity: function() {
312 var selectionSize = this.passwordsList.selectedItems.length;
313 this.removeRow.disabled = selectionSize == 0;
314 this.showHidePassword.disabled = selectionSize == 0;
315 this.removeAll.disabled = this.passwordsList.length == 0;
316 },
317
318 /**
319 * Callback from selection model
320 * @param {!cr.Event} ce Event with change info.
321 * @private
322 */
323 handleOnSelectionChange_: function(ce) {
324 this.passwordLabel.textContent = "";
325 this.showHidePassword.textContent = templateData.passwordsShowButton;
326 this.showingPassword = false;
327 this.updateButtonSensitivity();
328 },
329 };
330
331 /**
332 * Create a new passwords list area.
333 * @constructor
334 * @extends {cr.ui.div}
335 */
336 var PasswordExceptionsListArea = cr.ui.define('div');
337
338 PasswordExceptionsListArea.prototype = {
339 __proto__: HTMLDivElement.prototype,
340
341 decorate: function() {
342 this.passwordExceptionsList = this.querySelector('list');
343 this.passwordExceptionsList.listArea = this;
344
345 PasswordExceptionsList.decorate(this.passwordExceptionsList);
346 this.passwordExceptionsList.selectionModel.addEventListener(
347 'change', this.handleOnSelectionChange_.bind(this));
348
349 var removeRow = cr.doc.createElement('button');
350 removeRow.textContent = templateData.passwordsRemoveButton;
351 this.appendChild(removeRow);
352 this.removeRow = removeRow;
353
354 var removeAll = cr.doc.createElement('button');
355 removeAll.textContent = templateData.passwordsRemoveAllButton;
356 this.appendChild(removeAll);
357 this.removeAll = removeAll;
358
359 var self = this;
360 removeRow.onclick = function(event) {
361 self.passwordExceptionsList.removeSelectedRow();
362 };
363
364 removeAll.onclick = function(event) {
365 PasswordManager.removeAllPasswordExceptions();
366 };
367
368 this.updateButtonSensitivity();
369 },
370
371 /**
372 * Update the button's states
373 */
374 updateButtonSensitivity: function() {
375 var selectionSize = this.passwordExceptionsList.selectedItems.length;
376 this.removeRow.disabled = selectionSize == 0;
377 this.removeAll.disabled = this.passwordExceptionsList.length == 0;
378 },
379
380 /**
381 * Callback from selection model
382 * @param {!cr.Event} ce Event with change info.
383 * @private
384 */
385 handleOnSelectionChange_: function(ce) {
386 this.updateButtonSensitivity();
387 },
388 };
389
390
391 return { 228 return {
392 PasswordsListItem: PasswordsListItem, 229 PasswordListItem: PasswordListItem,
393 PasswordExceptionsListItem: PasswordExceptionsListItem, 230 PasswordExceptionsListItem: PasswordExceptionsListItem,
394 PasswordsList: PasswordsList, 231 PasswordsList: PasswordsList,
395 PasswordExceptionsList: PasswordExceptionsList, 232 PasswordExceptionsList: PasswordExceptionsList,
396 PasswordsListArea: PasswordsListArea,
397 PasswordExceptionsListArea: PasswordExceptionsListArea
398 }; 233 };
399 }); 234 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698