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