OLD | NEW |
---|---|
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 }); |
OLD | NEW |