| 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; |
| 9 /** @const */ var List = cr.ui.List; | 11 /** @const */ var List = cr.ui.List; |
| 10 | 12 |
| 11 /** | 13 /** |
| 12 * Creates a new passwords list item. | 14 * Creates a new passwords list item. |
| 13 * @param {ArrayDataModel} dataModel The data model that contains this item. | 15 * @param {ArrayDataModel} dataModel The data model that contains this item. |
| 14 * @param {Array} entry An array of the form [url, username, password]. When | 16 * @param {Array} entry An array of the form [url, username, password]. When |
| 15 * the list has been filtered, a fourth element [index] may be present. | 17 * the list has been filtered, a fourth element [index] may be present. |
| 16 * @param {boolean} showPasswords If true, add a button to the element to | 18 * @param {boolean} showPasswords If true, add a button to the element to |
| 17 * allow the user to reveal the saved password. | 19 * allow the user to reveal the saved password. |
| 18 * @constructor | 20 * @constructor |
| 19 * @extends {cr.ui.ListItem} | 21 * @extends {options.InlineEditableItem} |
| 20 */ | 22 */ |
| 21 function PasswordListItem(dataModel, entry, showPasswords) { | 23 function PasswordListItem(dataModel, entry, showPasswords) { |
| 22 var el = cr.doc.createElement('div'); | 24 var el = cr.doc.createElement('div'); |
| 23 el.dataItem = entry; | 25 el.dataItem = entry; |
| 24 el.dataModel = dataModel; | 26 el.dataModel = dataModel; |
| 25 el.__proto__ = PasswordListItem.prototype; | 27 el.__proto__ = PasswordListItem.prototype; |
| 26 el.decorate(showPasswords); | 28 el.decorate(showPasswords); |
| 27 | 29 |
| 28 return el; | 30 return el; |
| 29 } | 31 } |
| 30 | 32 |
| 31 PasswordListItem.prototype = { | 33 PasswordListItem.prototype = { |
| 32 __proto__: DeletableItem.prototype, | 34 __proto__: InlineEditableItem.prototype, |
| 33 | 35 |
| 34 /** @override */ | 36 /** @override */ |
| 35 decorate: function(showPasswords) { | 37 decorate: function(showPasswords) { |
| 36 DeletableItem.prototype.decorate.call(this); | 38 InlineEditableItem.prototype.decorate.call(this); |
| 39 |
| 40 // The user can edit the saved passwords if and only if he can reveal |
| 41 // them. |
| 42 this.editable = showPasswords; |
| 37 | 43 |
| 38 // The URL of the site. | 44 // The URL of the site. |
| 39 var urlLabel = this.ownerDocument.createElement('div'); | 45 var urlLabel = this.ownerDocument.createElement('div'); |
| 40 urlLabel.classList.add('favicon-cell'); | 46 urlLabel.classList.add('favicon-cell'); |
| 41 urlLabel.classList.add('weakrtl'); | 47 urlLabel.classList.add('weakrtl'); |
| 42 urlLabel.classList.add('url'); | 48 urlLabel.classList.add('url'); |
| 43 urlLabel.setAttribute('title', this.url); | 49 urlLabel.setAttribute('title', this.url); |
| 44 urlLabel.textContent = this.url; | 50 urlLabel.textContent = this.url; |
| 45 | 51 |
| 46 // The favicon URL is prefixed with "origin/", which essentially removes | 52 // The favicon URL is prefixed with "origin/", which essentially removes |
| (...skipping 18 matching lines...) Expand all Loading... |
| 65 | 71 |
| 66 // The password input field. | 72 // The password input field. |
| 67 var passwordInput = this.ownerDocument.createElement('input'); | 73 var passwordInput = this.ownerDocument.createElement('input'); |
| 68 passwordInput.type = 'password'; | 74 passwordInput.type = 'password'; |
| 69 passwordInput.className = 'inactive-password'; | 75 passwordInput.className = 'inactive-password'; |
| 70 passwordInput.readOnly = true; | 76 passwordInput.readOnly = true; |
| 71 passwordInput.value = showPasswords ? this.password : '********'; | 77 passwordInput.value = showPasswords ? this.password : '********'; |
| 72 passwordInputDiv.appendChild(passwordInput); | 78 passwordInputDiv.appendChild(passwordInput); |
| 73 this.passwordField = passwordInput; | 79 this.passwordField = passwordInput; |
| 74 | 80 |
| 75 // The show/hide button. | |
| 76 if (showPasswords) { | 81 if (showPasswords) { |
| 82 // The show/hide button. |
| 77 var button = this.ownerDocument.createElement('button'); | 83 var button = this.ownerDocument.createElement('button'); |
| 78 button.hidden = true; | 84 button.hidden = true; |
| 79 button.className = 'list-inline-button custom-appearance'; | 85 button.className = 'list-inline-button custom-appearance'; |
| 80 button.textContent = loadTimeData.getString('passwordShowButton'); | 86 button.textContent = loadTimeData.getString('passwordShowButton'); |
| 81 button.addEventListener('click', this.onClick_.bind(this), true); | 87 button.addEventListener('click', this.onClick_.bind(this), true); |
| 82 button.addEventListener('mousedown', function(event) { | 88 button.addEventListener('mousedown', function(event) { |
| 83 // Don't focus on this button by mousedown. | 89 // Don't focus on this button by mousedown. |
| 84 event.preventDefault(); | 90 event.preventDefault(); |
| 85 // Don't handle list item selection. It causes focus change. | 91 // Don't handle list item selection. It causes focus change. |
| 86 event.stopPropagation(); | 92 event.stopPropagation(); |
| 87 }, false); | 93 }, false); |
| 88 passwordInputDiv.appendChild(button); | 94 passwordInputDiv.appendChild(button); |
| 89 this.passwordShowButton = button; | 95 this.passwordShowButton = button; |
| 96 |
| 97 // Makes the password input field editable. |
| 98 this.addEditField(passwordInput, null); |
| 99 this.addEventListener('canceledit', this.onEditCancelled_); |
| 100 this.addEventListener('commitedit', this.onEditCommitted_); |
| 90 } | 101 } |
| 91 | 102 |
| 92 this.contentElement.appendChild(passwordInputDiv); | 103 this.contentElement.appendChild(passwordInputDiv); |
| 93 }, | 104 }, |
| 94 | 105 |
| 95 /** @override */ | 106 /** @override */ |
| 96 selectionChanged: function() { | 107 selectionChanged: function() { |
| 108 InlineEditableItem.prototype.selectionChanged.call(this); |
| 109 |
| 97 var input = this.passwordField; | 110 var input = this.passwordField; |
| 98 var button = this.passwordShowButton; | 111 var button = this.passwordShowButton; |
| 99 // The button doesn't exist when passwords can't be shown. | 112 // The button doesn't exist when passwords can't be shown. |
| 100 if (!button) | 113 if (!button) |
| 101 return; | 114 return; |
| 102 | 115 |
| 103 if (this.selected) { | 116 if (this.selected) { |
| 104 input.classList.remove('inactive-password'); | 117 input.classList.remove('inactive-password'); |
| 105 button.hidden = false; | 118 button.hidden = false; |
| 106 } else { | 119 } else { |
| 107 input.classList.add('inactive-password'); | 120 input.classList.add('inactive-password'); |
| 108 button.hidden = true; | 121 button.hidden = true; |
| 109 } | 122 } |
| 110 }, | 123 }, |
| 111 | 124 |
| 125 /** @override */ |
| 126 get currentInputIsValid() { |
| 127 return !!this.passwordField.value; |
| 128 }, |
| 129 |
| 130 /** @override */ |
| 131 get hasBeenEdited() { |
| 132 return this.passwordField.value != this.password; |
| 133 }, |
| 134 |
| 112 /** | 135 /** |
| 113 * Reveals the plain text password of this entry. | 136 * Reveals the plain text password of this entry. |
| 114 */ | 137 */ |
| 115 showPassword: function(password) { | 138 showPassword: function(password) { |
| 139 this.password = password; |
| 116 this.passwordField.value = password; | 140 this.passwordField.value = password; |
| 117 this.passwordField.type = 'text'; | 141 this.passwordField.type = 'text'; |
| 142 this.passwordField.readOnly = false; |
| 118 | 143 |
| 119 var button = this.passwordShowButton; | 144 var button = this.passwordShowButton; |
| 120 if (button) | 145 if (button) |
| 121 button.textContent = loadTimeData.getString('passwordHideButton'); | 146 button.textContent = loadTimeData.getString('passwordHideButton'); |
| 122 }, | 147 }, |
| 123 | 148 |
| 124 /** | 149 /** |
| 125 * Hides the plain text password of this entry. | 150 * Hides the plain text password of this entry. |
| 126 */ | 151 */ |
| 127 hidePassword: function() { | 152 hidePassword: function() { |
| 128 this.passwordField.type = 'password'; | 153 this.passwordField.type = 'password'; |
| 154 this.passwordField.readOnly = true; |
| 129 | 155 |
| 130 var button = this.passwordShowButton; | 156 var button = this.passwordShowButton; |
| 131 if (button) | 157 if (button) |
| 132 button.textContent = loadTimeData.getString('passwordShowButton'); | 158 button.textContent = loadTimeData.getString('passwordShowButton'); |
| 133 }, | 159 }, |
| 134 | 160 |
| 135 /** | 161 /** |
| 136 * Get the original index of this item in the data model. | 162 * Get the original index of this item in the data model. |
| 137 * @return {number} The index. | 163 * @return {number} The index. |
| 138 * @private | 164 * @private |
| (...skipping 11 matching lines...) Expand all Loading... |
| 150 onClick_: function(event) { | 176 onClick_: function(event) { |
| 151 if (this.passwordField.type == 'password') { | 177 if (this.passwordField.type == 'password') { |
| 152 // After the user is authenticated, showPassword() will be called. | 178 // After the user is authenticated, showPassword() will be called. |
| 153 PasswordManager.requestShowPassword(this.getOriginalIndex_()); | 179 PasswordManager.requestShowPassword(this.getOriginalIndex_()); |
| 154 } else { | 180 } else { |
| 155 this.hidePassword(); | 181 this.hidePassword(); |
| 156 } | 182 } |
| 157 }, | 183 }, |
| 158 | 184 |
| 159 /** | 185 /** |
| 186 * Called when cancelling a password edit. Resets the password input field. |
| 187 * @param {Event} event The canceledit event. |
| 188 * @private |
| 189 */ |
| 190 onEditCancelled_: function(event) { |
| 191 this.passwordField.value = this.password; |
| 192 }, |
| 193 |
| 194 /** |
| 195 * Called when committing a password edit. Updates the password. |
| 196 * @param {Event} event The commitedit event. |
| 197 * @private |
| 198 */ |
| 199 onEditCommitted_: function(event) { |
| 200 this.password = this.passwordField.value; |
| 201 PasswordManager.updatePassword( |
| 202 this.getOriginalIndex_(), this.passwordField.value); |
| 203 }, |
| 204 |
| 205 /** |
| 160 * Get and set the URL for the entry. | 206 * Get and set the URL for the entry. |
| 161 * @type {string} | 207 * @type {string} |
| 162 */ | 208 */ |
| 163 get url() { | 209 get url() { |
| 164 return this.dataItem[0]; | 210 return this.dataItem[0]; |
| 165 }, | 211 }, |
| 166 set url(url) { | 212 set url(url) { |
| 167 this.dataItem[0] = url; | 213 this.dataItem[0] = url; |
| 168 }, | 214 }, |
| 169 | 215 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 return this.dataItem; | 285 return this.dataItem; |
| 240 }, | 286 }, |
| 241 set url(url) { | 287 set url(url) { |
| 242 this.dataItem = url; | 288 this.dataItem = url; |
| 243 }, | 289 }, |
| 244 }; | 290 }; |
| 245 | 291 |
| 246 /** | 292 /** |
| 247 * Create a new passwords list. | 293 * Create a new passwords list. |
| 248 * @constructor | 294 * @constructor |
| 249 * @extends {cr.ui.List} | 295 * @extends {options.InlineEditableItemList} |
| 250 */ | 296 */ |
| 251 var PasswordsList = cr.ui.define('list'); | 297 var PasswordsList = cr.ui.define('list'); |
| 252 | 298 |
| 253 PasswordsList.prototype = { | 299 PasswordsList.prototype = { |
| 254 __proto__: DeletableItemList.prototype, | 300 __proto__: InlineEditableItemList.prototype, |
| 255 | 301 |
| 256 /** | 302 /** |
| 257 * Whether passwords can be revealed or not. | 303 * Whether passwords can be revealed or not. |
| 258 * @type {boolean} | 304 * @type {boolean} |
| 259 * @private | 305 * @private |
| 260 */ | 306 */ |
| 261 showPasswords_: true, | 307 showPasswords_: true, |
| 262 | 308 |
| 263 /** @override */ | 309 /** @override */ |
| 264 decorate: function() { | 310 decorate: function() { |
| 265 DeletableItemList.prototype.decorate.call(this); | 311 InlineEditableItemList.prototype.decorate.call(this); |
| 266 Preferences.getInstance().addEventListener( | 312 Preferences.getInstance().addEventListener( |
| 267 'profile.password_manager_allow_show_passwords', | 313 'profile.password_manager_allow_show_passwords', |
| 268 this.onPreferenceChanged_.bind(this)); | 314 this.onPreferenceChanged_.bind(this)); |
| 269 }, | 315 }, |
| 270 | 316 |
| 271 /** | 317 /** |
| 272 * Listener for changes on the preference. | 318 * Listener for changes on the preference. |
| 273 * @param {Event} event The preference update event. | 319 * @param {Event} event The preference update event. |
| 274 * @private | 320 * @private |
| 275 */ | 321 */ |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 }, | 380 }, |
| 335 }; | 381 }; |
| 336 | 382 |
| 337 return { | 383 return { |
| 338 PasswordListItem: PasswordListItem, | 384 PasswordListItem: PasswordListItem, |
| 339 PasswordExceptionsListItem: PasswordExceptionsListItem, | 385 PasswordExceptionsListItem: PasswordExceptionsListItem, |
| 340 PasswordsList: PasswordsList, | 386 PasswordsList: PasswordsList, |
| 341 PasswordExceptionsList: PasswordExceptionsList, | 387 PasswordExceptionsList: PasswordExceptionsList, |
| 342 }; | 388 }; |
| 343 }); | 389 }); |
| OLD | NEW |