OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; | 6 /** @const */ var ArrayDataModel = cr.ui.ArrayDataModel; |
7 /** @const */ var DeletableItemList = options.DeletableItemList; | 7 /** @const */ var DeletableItemList = options.DeletableItemList; |
8 /** @const */ var DeletableItem = options.DeletableItem; | 8 /** @const */ var DeletableItem = options.DeletableItem; |
9 /** @const */ var InlineEditableItemList = options.InlineEditableItemList; | |
10 /** @const */ var InlineEditableItem = options.InlineEditableItem; | |
11 /** @const */ var List = cr.ui.List; | 9 /** @const */ var List = cr.ui.List; |
12 | 10 |
13 /** | 11 /** |
14 * Creates a new passwords list item. | 12 * Creates a new passwords list item. |
15 * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this | 13 * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this |
16 * item. | 14 * item. |
17 * @param {Array} entry An array of the form [url, username, password]. When | 15 * @param {Array} entry An array of the form [url, username, password]. When |
18 * the list has been filtered, a fourth element [index] may be present. | 16 * the list has been filtered, a fourth element [index] may be present. |
19 * @param {boolean} showPasswords If true, add a button to the element to | 17 * @param {boolean} showPasswords If true, add a button to the element to |
20 * allow the user to reveal the saved password. | 18 * allow the user to reveal the saved password. |
21 * @constructor | 19 * @constructor |
22 * @extends {options.InlineEditableItem} | 20 * @extends {options.DeletableItem} |
23 */ | 21 */ |
24 function PasswordListItem(dataModel, entry, showPasswords) { | 22 function PasswordListItem(dataModel, entry, showPasswords) { |
25 var el = cr.doc.createElement('div'); | 23 var el = cr.doc.createElement('div'); |
26 el.dataItem = entry; | 24 el.dataItem = entry; |
27 el.dataModel = dataModel; | 25 el.dataModel = dataModel; |
28 el.__proto__ = PasswordListItem.prototype; | 26 el.__proto__ = PasswordListItem.prototype; |
29 el.decorate(showPasswords); | 27 el.decorate(showPasswords); |
30 | 28 |
31 return el; | 29 return el; |
32 } | 30 } |
33 | 31 |
34 PasswordListItem.prototype = { | 32 PasswordListItem.prototype = { |
35 __proto__: InlineEditableItem.prototype, | 33 __proto__: DeletableItem.prototype, |
36 | 34 |
37 /** @override */ | 35 /** @override */ |
38 decorate: function(showPasswords) { | 36 decorate: function(showPasswords) { |
39 InlineEditableItem.prototype.decorate.call(this); | 37 DeletableItem.prototype.decorate.call(this); |
40 | 38 |
41 this.isPlaceholder = !this.url; | 39 // The URL of the site. |
| 40 var urlLabel = this.ownerDocument.createElement('div'); |
| 41 urlLabel.classList.add('favicon-cell'); |
| 42 urlLabel.classList.add('weakrtl'); |
| 43 urlLabel.classList.add('url'); |
| 44 urlLabel.setAttribute('title', this.url); |
| 45 urlLabel.textContent = this.url; |
42 | 46 |
43 this.contentElement.appendChild(this.createUrlElement()); | 47 // The favicon URL is prefixed with "origin/", which essentially removes |
44 this.contentElement.appendChild(this.createUsernameElement()); | 48 // the URL path past the top-level domain and ensures that a scheme (e.g., |
| 49 // http) is being used. This ensures that the favicon returned is the |
| 50 // default favicon for the domain and that the URL has a scheme if none |
| 51 // is present in the password manager. |
| 52 urlLabel.style.backgroundImage = getFaviconImageSet( |
| 53 'origin/' + this.url, 16); |
| 54 this.contentElement.appendChild(urlLabel); |
45 | 55 |
| 56 // The stored username. |
| 57 var usernameLabel = this.ownerDocument.createElement('div'); |
| 58 usernameLabel.className = 'name'; |
| 59 usernameLabel.textContent = this.username; |
| 60 usernameLabel.title = this.username; |
| 61 this.contentElement.appendChild(usernameLabel); |
| 62 |
| 63 // The stored password. |
46 var passwordInputDiv = this.ownerDocument.createElement('div'); | 64 var passwordInputDiv = this.ownerDocument.createElement('div'); |
47 passwordInputDiv.className = 'password'; | 65 passwordInputDiv.className = 'password'; |
48 | 66 |
49 // The password input field. | 67 // The password input field. |
50 var passwordInput = this.ownerDocument.createElement('input'); | 68 var passwordInput = this.ownerDocument.createElement('input'); |
51 passwordInput.type = 'password'; | 69 passwordInput.type = 'password'; |
52 if (!this.isPlaceholder) { | 70 passwordInput.className = 'inactive-password'; |
53 passwordInput.className = 'inactive-password'; | 71 passwordInput.readOnly = true; |
54 passwordInput.readOnly = true; | 72 passwordInput.value = showPasswords ? this.password : '********'; |
55 passwordInput.value = showPasswords ? this.password : '********'; | 73 passwordInputDiv.appendChild(passwordInput); |
56 } | |
57 this.passwordField = passwordInput; | 74 this.passwordField = passwordInput; |
58 | 75 |
59 // Makes the password input field editable. | 76 // The show/hide button. |
60 this.addEditField(passwordInput, null); | 77 if (showPasswords) { |
61 | 78 var button = this.ownerDocument.createElement('button'); |
62 // Keeps the password validity updated. | 79 button.hidden = true; |
63 this.updatePasswordValidity_(); | 80 button.className = 'list-inline-button custom-appearance'; |
64 passwordInput.addEventListener('input', function(event) { | 81 button.textContent = loadTimeData.getString('passwordShowButton'); |
65 this.updatePasswordValidity_(); | 82 button.addEventListener('click', this.onClick_.bind(this), true); |
66 }.bind(this)); | 83 button.addEventListener('mousedown', function(event) { |
67 | |
68 passwordInputDiv.appendChild(passwordInput); | |
69 | |
70 // The list-inline buttons. | |
71 if (!this.isPlaceholder) { | |
72 // The container of the list-inline buttons. | |
73 var buttonsContainer = this.ownerDocument.createElement('div'); | |
74 buttonsContainer.className = 'list-inline-buttons-container'; | |
75 | |
76 var mousedownEventHandler = function(event) { | |
77 // Don't focus on this button by mousedown. | 84 // Don't focus on this button by mousedown. |
78 event.preventDefault(); | 85 event.preventDefault(); |
79 // Don't handle list item selection. It causes focus change. | 86 // Don't handle list item selection. It causes focus change. |
80 event.stopPropagation(); | 87 event.stopPropagation(); |
81 }; | 88 }, false); |
82 | 89 passwordInputDiv.appendChild(button); |
83 // The overwrite button. | 90 this.passwordShowButton = button; |
84 var overwriteButton = this.ownerDocument.createElement('button'); | |
85 overwriteButton.className = 'list-inline-button custom-appearance'; | |
86 overwriteButton.textContent = loadTimeData.getString( | |
87 'passwordOverwriteButton'); | |
88 overwriteButton.addEventListener( | |
89 'click', this.onClickOverwriteButton_.bind(this), true); | |
90 overwriteButton.addEventListener( | |
91 'mousedown', mousedownEventHandler, false); | |
92 buttonsContainer.appendChild(overwriteButton); | |
93 this.passwordOverwriteButton = overwriteButton; | |
94 | |
95 // The show/hide button. | |
96 if (showPasswords) { | |
97 var button = this.ownerDocument.createElement('button'); | |
98 button.className = 'list-inline-button custom-appearance'; | |
99 button.textContent = loadTimeData.getString('passwordShowButton'); | |
100 button.addEventListener( | |
101 'click', this.onClickShowButton_.bind(this), true); | |
102 button.addEventListener('mousedown', mousedownEventHandler, false); | |
103 buttonsContainer.appendChild(button); | |
104 this.passwordShowButton = button; | |
105 } | |
106 | |
107 passwordInputDiv.appendChild(buttonsContainer); | |
108 } | 91 } |
109 | 92 |
110 this.contentElement.appendChild(passwordInputDiv); | 93 this.contentElement.appendChild(passwordInputDiv); |
111 | |
112 // Adds the event listeners for editing. | |
113 this.addEventListener('canceledit', this.resetInputs); | |
114 this.addEventListener('commitedit', this.finishEdit); | |
115 }, | |
116 | |
117 /** | |
118 * Constructs and returns the URL element for this item. | |
119 * @return {HTMLElement} The URL element. | |
120 * @protected | |
121 */ | |
122 createUrlElement: function() { | |
123 var urlEl = this.ownerDocument.createElement('div'); | |
124 urlEl.className = 'favicon-cell weakrtl url'; | |
125 urlEl.setAttribute('title', this.url); | |
126 urlEl.textContent = this.url; | |
127 | |
128 // The favicon URL is prefixed with "origin/", which essentially removes | |
129 // the URL path past the top-level domain and ensures that a scheme (e.g., | |
130 // http) is being used. This ensures that the favicon returned is the | |
131 // default favicon for the domain and that the URL has a scheme if none is | |
132 // present in the password manager. | |
133 urlEl.style.backgroundImage = getFaviconImageSet( | |
134 'origin/' + this.url, 16); | |
135 return urlEl; | |
136 }, | |
137 | |
138 /** | |
139 * Constructs and returns the username element for this item. | |
140 * @return {HTMLElement} The username element. | |
141 * @protected | |
142 */ | |
143 createUsernameElement: function() { | |
144 var usernameEl = this.ownerDocument.createElement('div'); | |
145 usernameEl.className = 'name'; | |
146 usernameEl.textContent = this.username; | |
147 usernameEl.title = this.username; | |
148 return usernameEl; | |
149 }, | 94 }, |
150 | 95 |
151 /** @override */ | 96 /** @override */ |
152 selectionChanged: function() { | 97 selectionChanged: function() { |
153 InlineEditableItem.prototype.selectionChanged.call(this); | 98 var input = this.passwordField; |
154 | 99 var button = this.passwordShowButton; |
155 // Don't set 'inactive-password' class for the placeholder so that it | 100 // The button doesn't exist when passwords can't be shown. |
156 // shows the background and the borders. | 101 if (!button) |
157 if (this.isPlaceholder) | |
158 return; | 102 return; |
159 | 103 |
160 this.passwordField.classList.toggle('inactive-password', !this.selected); | 104 if (this.selected) { |
161 }, | 105 input.classList.remove('inactive-password'); |
162 | 106 button.hidden = false; |
163 /** @override */ | 107 } else { |
164 get currentInputIsValid() { | 108 input.classList.add('inactive-password'); |
165 return !!this.passwordField.value; | 109 button.hidden = true; |
| 110 } |
166 }, | 111 }, |
167 | 112 |
168 /** | 113 /** |
169 * Returns if the password has been edited. | 114 * Reveals the plain text password of this entry. |
170 * @return {boolean} Whether the password has been edited. | |
171 * @protected | |
172 */ | |
173 passwordHasBeenEdited: function() { | |
174 return this.passwordField.value != this.password || this.overwriting; | |
175 }, | |
176 | |
177 /** @override */ | |
178 get hasBeenEdited() { | |
179 return this.passwordHasBeenEdited(); | |
180 }, | |
181 | |
182 /** | |
183 * Reveals the plain text password of this entry. Never called for the Add | |
184 * New Entry row. | |
185 * @param {string} password The plain text password. | |
186 */ | 115 */ |
187 showPassword: function(password) { | 116 showPassword: function(password) { |
188 this.overwriting = false; | 117 this.passwordField.value = password; |
189 this.password = password; | |
190 this.setPasswordFieldValue_(password); | |
191 this.passwordField.type = 'text'; | 118 this.passwordField.type = 'text'; |
192 this.passwordField.readOnly = false; | |
193 | 119 |
194 this.passwordOverwriteButton.hidden = true; | |
195 var button = this.passwordShowButton; | 120 var button = this.passwordShowButton; |
196 if (button) | 121 if (button) |
197 button.textContent = loadTimeData.getString('passwordHideButton'); | 122 button.textContent = loadTimeData.getString('passwordHideButton'); |
198 }, | 123 }, |
199 | 124 |
200 /** | 125 /** |
201 * Hides the plain text password of this entry. Never called for the Add | 126 * Hides the plain text password of this entry. |
202 * New Entry row. | |
203 * @private | |
204 */ | 127 */ |
205 hidePassword_: function() { | 128 hidePassword: function() { |
206 this.passwordField.type = 'password'; | 129 this.passwordField.type = 'password'; |
207 this.passwordField.readOnly = true; | |
208 | 130 |
209 this.passwordOverwriteButton.hidden = false; | |
210 var button = this.passwordShowButton; | 131 var button = this.passwordShowButton; |
211 if (button) | 132 if (button) |
212 button.textContent = loadTimeData.getString('passwordShowButton'); | 133 button.textContent = loadTimeData.getString('passwordShowButton'); |
213 }, | 134 }, |
214 | 135 |
215 /** | 136 /** |
216 * Resets the input fields to their original values and states. | |
217 * @protected | |
218 */ | |
219 resetInputs: function() { | |
220 this.finishOverwriting_(); | |
221 this.setPasswordFieldValue_(this.password); | |
222 }, | |
223 | |
224 /** | |
225 * Commits the new data to the browser. | |
226 * @protected | |
227 */ | |
228 finishEdit: function() { | |
229 this.password = this.passwordField.value; | |
230 this.finishOverwriting_(); | |
231 PasswordManager.updatePassword( | |
232 this.getOriginalIndex_(), this.passwordField.value); | |
233 }, | |
234 | |
235 /** | |
236 * Called with the response of the browser, which indicates the validity of | |
237 * the URL. | |
238 * @param {string} url The URL. | |
239 * @param {boolean} valid The validity of the URL. | |
240 */ | |
241 originValidityCheckComplete: function(url, valid) { | |
242 assertNotReached(); | |
243 }, | |
244 | |
245 /** | |
246 * Updates the custom validity of the password input field. | |
247 * @private | |
248 */ | |
249 updatePasswordValidity_: function() { | |
250 this.passwordField.setCustomValidity(this.passwordField.value ? | |
251 '' : loadTimeData.getString('editPasswordInvalidPasswordTooltip')); | |
252 }, | |
253 | |
254 /** | |
255 * Finishes password overwriting. | |
256 * @private | |
257 */ | |
258 finishOverwriting_: function() { | |
259 if (!this.overwriting) | |
260 return; | |
261 this.overwriting = false; | |
262 this.passwordOverwriteButton.hidden = false; | |
263 this.passwordField.readOnly = true; | |
264 }, | |
265 | |
266 /** | |
267 * Sets the value of the password input field. | |
268 * @param {string} password The new value. | |
269 * @private | |
270 */ | |
271 setPasswordFieldValue_: function(password) { | |
272 this.passwordField.value = password; | |
273 this.updatePasswordValidity_(); | |
274 }, | |
275 | |
276 /** | |
277 * Get the original index of this item in the data model. | 137 * Get the original index of this item in the data model. |
278 * @return {number} The index. | 138 * @return {number} The index. |
279 * @private | 139 * @private |
280 */ | 140 */ |
281 getOriginalIndex_: function() { | 141 getOriginalIndex_: function() { |
282 var index = this.dataItem[3]; | 142 var index = this.dataItem[3]; |
283 return index ? index : this.dataModel.indexOf(this.dataItem); | 143 return index ? index : this.dataModel.indexOf(this.dataItem); |
284 }, | 144 }, |
285 | 145 |
286 /** | 146 /** |
287 * Called when clicking the overwrite button. Allows the user to overwrite | |
288 * the hidden password. | |
289 * @param {Event} event The click event. | |
290 * @private | |
291 */ | |
292 onClickOverwriteButton_: function(event) { | |
293 this.overwriting = true; | |
294 this.passwordOverwriteButton.hidden = true; | |
295 | |
296 this.setPasswordFieldValue_(''); | |
297 this.passwordField.readOnly = false; | |
298 this.passwordField.focus(); | |
299 }, | |
300 | |
301 /** | |
302 * On-click event handler. Swaps the type of the input field from password | 147 * On-click event handler. Swaps the type of the input field from password |
303 * to text and back. | 148 * to text and back. |
304 * @private | 149 * @private |
305 */ | 150 */ |
306 onClickShowButton_: function(event) { | 151 onClick_: function(event) { |
307 // Prevents committing an edit. | |
308 this.resetInputs(); | |
309 | |
310 if (this.passwordField.type == 'password') { | 152 if (this.passwordField.type == 'password') { |
311 // After the user is authenticated, showPassword() will be called. | 153 // After the user is authenticated, showPassword() will be called. |
312 PasswordManager.requestShowPassword(this.getOriginalIndex_()); | 154 PasswordManager.requestShowPassword(this.getOriginalIndex_()); |
313 } else { | 155 } else { |
314 this.hidePassword_(); | 156 this.hidePassword(); |
315 } | 157 } |
316 }, | 158 }, |
317 | 159 |
318 /** | 160 /** |
319 * Get and set the URL for the entry. | 161 * Get and set the URL for the entry. |
320 * @type {string} | 162 * @type {string} |
321 */ | 163 */ |
322 get url() { | 164 get url() { |
323 return this.dataItem[0] || ''; | 165 return this.dataItem[0]; |
324 }, | 166 }, |
325 set url(url) { | 167 set url(url) { |
326 this.dataItem[0] = url; | 168 this.dataItem[0] = url; |
327 }, | 169 }, |
328 | 170 |
329 /** | 171 /** |
330 * Get and set the username for the entry. | 172 * Get and set the username for the entry. |
331 * @type {string} | 173 * @type {string} |
332 */ | 174 */ |
333 get username() { | 175 get username() { |
334 return this.dataItem[1] || ''; | 176 return this.dataItem[1]; |
335 }, | 177 }, |
336 set username(username) { | 178 set username(username) { |
337 this.dataItem[1] = username; | 179 this.dataItem[1] = username; |
338 }, | 180 }, |
339 | 181 |
340 /** | 182 /** |
341 * Get and set the password for the entry. | 183 * Get and set the password for the entry. |
342 * @type {string} | 184 * @type {string} |
343 */ | 185 */ |
344 get password() { | 186 get password() { |
345 return this.dataItem[2] || ''; | 187 return this.dataItem[2]; |
346 }, | 188 }, |
347 set password(password) { | 189 set password(password) { |
348 this.dataItem[2] = password; | 190 this.dataItem[2] = password; |
349 }, | 191 }, |
350 }; | 192 }; |
351 | 193 |
352 /** | 194 /** |
353 * Creates a new passwords list item for the Add New Entry row. | |
354 * @param {ArrayDataModel} dataModel The data model that contains this item. | |
355 * @constructor | |
356 * @extends {options.passwordManager.PasswordListItem} | |
357 */ | |
358 function PasswordAddRowListItem(dataModel) { | |
359 var el = cr.doc.createElement('div'); | |
360 el.dataItem = []; | |
361 el.dataModel = dataModel; | |
362 el.__proto__ = PasswordAddRowListItem.prototype; | |
363 el.decorate(); | |
364 | |
365 return el; | |
366 } | |
367 | |
368 PasswordAddRowListItem.prototype = { | |
369 __proto__: PasswordListItem.prototype, | |
370 | |
371 /** @override */ | |
372 decorate: function() { | |
373 PasswordListItem.prototype.decorate.call(this, false); | |
374 | |
375 this.urlField.placeholder = loadTimeData.getString( | |
376 'newPasswordUrlFieldPlaceholder'); | |
377 this.usernameField.placeholder = loadTimeData.getString( | |
378 'newPasswordUsernameFieldPlaceholder'); | |
379 this.passwordField.placeholder = loadTimeData.getString( | |
380 'newPasswordPasswordFieldPlaceholder'); | |
381 | |
382 // Sets the validity of the URL initially. | |
383 this.setUrlValid_(false); | |
384 }, | |
385 | |
386 /** @override */ | |
387 createUrlElement: function() { | |
388 var urlEl = this.createEditableTextCell(''); | |
389 urlEl.className += ' favicon-cell weakrtl url'; | |
390 | |
391 var urlField = urlEl.querySelector('input'); | |
392 urlField.addEventListener('input', this.onUrlInput_.bind(this)); | |
393 this.urlField = urlField; | |
394 | |
395 return urlEl; | |
396 }, | |
397 | |
398 /** @override */ | |
399 createUsernameElement: function() { | |
400 var usernameEl = this.createEditableTextCell(''); | |
401 usernameEl.className = 'name'; | |
402 | |
403 this.usernameField = usernameEl.querySelector('input'); | |
404 | |
405 return usernameEl; | |
406 }, | |
407 | |
408 /** @override */ | |
409 get currentInputIsValid() { | |
410 return this.urlValidityKnown && this.urlIsValid && | |
411 this.passwordField.value; | |
412 }, | |
413 | |
414 /** @override */ | |
415 get hasBeenEdited() { | |
416 return this.urlField.value || this.usernameField.value || | |
417 this.passwordHasBeenEdited(); | |
418 }, | |
419 | |
420 /** @override */ | |
421 resetInputs: function() { | |
422 PasswordListItem.prototype.resetInputs.call(this); | |
423 | |
424 this.urlField.value = ''; | |
425 this.usernameField.value = ''; | |
426 | |
427 this.setUrlValid_(false); | |
428 }, | |
429 | |
430 /** @override */ | |
431 finishEdit: function() { | |
432 var newUrl = this.urlField.value; | |
433 var newUsername = this.usernameField.value; | |
434 var newPassword = this.passwordField.value; | |
435 this.resetInputs(); | |
436 | |
437 PasswordManager.addPassword(newUrl, newUsername, newPassword); | |
438 }, | |
439 | |
440 /** @override */ | |
441 originValidityCheckComplete: function(url, valid) { | |
442 if (url == this.urlField.value) | |
443 this.setUrlValid_(valid); | |
444 }, | |
445 | |
446 /** | |
447 * Updates whether the URL in the input is valid. | |
448 * @param {boolean} valid The validity of the URL. | |
449 * @private | |
450 */ | |
451 setUrlValid_: function(valid) { | |
452 this.urlIsValid = valid; | |
453 this.urlValidityKnown = true; | |
454 if (this.urlField) { | |
455 this.urlField.setCustomValidity(valid ? | |
456 '' : loadTimeData.getString('editPasswordInvalidUrlTooltip')); | |
457 } | |
458 }, | |
459 | |
460 /** | |
461 * Called when inputting to a URL input. | |
462 * @param {Event} event The input event. | |
463 * @private | |
464 */ | |
465 onUrlInput_: function(event) { | |
466 this.urlValidityKnown = false; | |
467 PasswordManager.checkOriginValidityForAdding(this.urlField.value); | |
468 }, | |
469 }; | |
470 | |
471 /** | |
472 * Creates a new PasswordExceptions list item. | 195 * Creates a new PasswordExceptions list item. |
473 * @param {Array} entry A pair of the form [url, username]. | 196 * @param {Array} entry A pair of the form [url, username]. |
474 * @constructor | 197 * @constructor |
475 * @extends {options.DeletableItem} | 198 * @extends {options.DeletableItem} |
476 */ | 199 */ |
477 function PasswordExceptionsListItem(entry) { | 200 function PasswordExceptionsListItem(entry) { |
478 var el = cr.doc.createElement('div'); | 201 var el = cr.doc.createElement('div'); |
479 el.dataItem = entry; | 202 el.dataItem = entry; |
480 el.__proto__ = PasswordExceptionsListItem.prototype; | 203 el.__proto__ = PasswordExceptionsListItem.prototype; |
481 el.decorate(); | 204 el.decorate(); |
482 | 205 |
483 return el; | 206 return el; |
484 } | 207 } |
485 | 208 |
486 PasswordExceptionsListItem.prototype = { | 209 PasswordExceptionsListItem.prototype = { |
487 __proto__: DeletableItem.prototype, | 210 __proto__: DeletableItem.prototype, |
488 | 211 |
489 /** | 212 /** |
490 * Call when an element is decorated as a list item. | 213 * Call when an element is decorated as a list item. |
491 */ | 214 */ |
492 decorate: function() { | 215 decorate: function() { |
493 DeletableItem.prototype.decorate.call(this); | 216 DeletableItem.prototype.decorate.call(this); |
494 | 217 |
495 // The URL of the site. | 218 // The URL of the site. |
496 var urlLabel = this.ownerDocument.createElement('div'); | 219 var urlLabel = this.ownerDocument.createElement('div'); |
497 urlLabel.className = 'url favicon-cell weakrtl'; | 220 urlLabel.className = 'url'; |
| 221 urlLabel.classList.add('favicon-cell'); |
| 222 urlLabel.classList.add('weakrtl'); |
498 urlLabel.textContent = this.url; | 223 urlLabel.textContent = this.url; |
499 | 224 |
500 // The favicon URL is prefixed with "origin/", which essentially removes | 225 // The favicon URL is prefixed with "origin/", which essentially removes |
501 // the URL path past the top-level domain and ensures that a scheme (e.g., | 226 // the URL path past the top-level domain and ensures that a scheme (e.g., |
502 // http) is being used. This ensures that the favicon returned is the | 227 // http) is being used. This ensures that the favicon returned is the |
503 // default favicon for the domain and that the URL has a scheme if none | 228 // default favicon for the domain and that the URL has a scheme if none |
504 // is present in the password manager. | 229 // is present in the password manager. |
505 urlLabel.style.backgroundImage = getFaviconImageSet( | 230 urlLabel.style.backgroundImage = getFaviconImageSet( |
506 'origin/' + this.url, 16); | 231 'origin/' + this.url, 16); |
507 this.contentElement.appendChild(urlLabel); | 232 this.contentElement.appendChild(urlLabel); |
508 }, | 233 }, |
509 | 234 |
510 /** | 235 /** |
511 * Get the url for the entry. | 236 * Get the url for the entry. |
512 * @type {string} | 237 * @type {string} |
513 */ | 238 */ |
514 get url() { | 239 get url() { |
515 return this.dataItem; | 240 return this.dataItem; |
516 }, | 241 }, |
517 set url(url) { | 242 set url(url) { |
518 this.dataItem = url; | 243 this.dataItem = url; |
519 }, | 244 }, |
520 }; | 245 }; |
521 | 246 |
522 /** | 247 /** |
523 * Create a new passwords list. | 248 * Create a new passwords list. |
524 * @constructor | 249 * @constructor |
525 * @extends {options.InlineEditableItemList} | 250 * @extends {options.DeletableItemList} |
526 */ | 251 */ |
527 var PasswordsList = cr.ui.define('list'); | 252 var PasswordsList = cr.ui.define('list'); |
528 | 253 |
529 PasswordsList.prototype = { | 254 PasswordsList.prototype = { |
530 __proto__: InlineEditableItemList.prototype, | 255 __proto__: DeletableItemList.prototype, |
531 | 256 |
532 /** | 257 /** |
533 * Whether passwords can be revealed or not. | 258 * Whether passwords can be revealed or not. |
534 * @type {boolean} | 259 * @type {boolean} |
535 * @private | 260 * @private |
536 */ | 261 */ |
537 showPasswords_: true, | 262 showPasswords_: true, |
538 | 263 |
539 /** @override */ | 264 /** @override */ |
540 decorate: function() { | 265 decorate: function() { |
541 InlineEditableItemList.prototype.decorate.call(this); | 266 DeletableItemList.prototype.decorate.call(this); |
542 Preferences.getInstance().addEventListener( | 267 Preferences.getInstance().addEventListener( |
543 'profile.password_manager_allow_show_passwords', | 268 'profile.password_manager_allow_show_passwords', |
544 this.onPreferenceChanged_.bind(this)); | 269 this.onPreferenceChanged_.bind(this)); |
545 }, | 270 }, |
546 | 271 |
547 /** | 272 /** |
548 * Listener for changes on the preference. | 273 * Listener for changes on the preference. |
549 * @param {Event} event The preference update event. | 274 * @param {Event} event The preference update event. |
550 * @private | 275 * @private |
551 */ | 276 */ |
552 onPreferenceChanged_: function(event) { | 277 onPreferenceChanged_: function(event) { |
553 this.showPasswords_ = event.value.value; | 278 this.showPasswords_ = event.value.value; |
554 this.redraw(); | 279 this.redraw(); |
555 }, | 280 }, |
556 | 281 |
557 /** | 282 /** |
558 * @override | 283 * @override |
559 * @param {Array} entry | 284 * @param {Array} entry |
560 */ | 285 */ |
561 createItem: function(entry) { | 286 createItem: function(entry) { |
562 if (!entry) | |
563 return new PasswordAddRowListItem(this.dataModel); | |
564 | |
565 var showPasswords = this.showPasswords_; | 287 var showPasswords = this.showPasswords_; |
566 | 288 |
567 if (loadTimeData.getBoolean('disableShowPasswords')) | 289 if (loadTimeData.getBoolean('disableShowPasswords')) |
568 showPasswords = false; | 290 showPasswords = false; |
569 | 291 |
570 return new PasswordListItem(this.dataModel, entry, showPasswords); | 292 return new PasswordListItem(this.dataModel, entry, showPasswords); |
571 }, | 293 }, |
572 | 294 |
573 /** @override */ | 295 /** @override */ |
574 deleteItemAtIndex: function(index) { | 296 deleteItemAtIndex: function(index) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 /** | 336 /** |
615 * The length of the list. | 337 * The length of the list. |
616 */ | 338 */ |
617 get length() { | 339 get length() { |
618 return this.dataModel.length; | 340 return this.dataModel.length; |
619 }, | 341 }, |
620 }; | 342 }; |
621 | 343 |
622 return { | 344 return { |
623 PasswordListItem: PasswordListItem, | 345 PasswordListItem: PasswordListItem, |
624 PasswordAddRowListItem: PasswordAddRowListItem, | |
625 PasswordExceptionsListItem: PasswordExceptionsListItem, | 346 PasswordExceptionsListItem: PasswordExceptionsListItem, |
626 PasswordsList: PasswordsList, | 347 PasswordsList: PasswordsList, |
627 PasswordExceptionsList: PasswordExceptionsList, | 348 PasswordExceptionsList: PasswordExceptionsList, |
628 }; | 349 }; |
629 }); | 350 }); |
OLD | NEW |