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

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

Issue 489103004: Allow editing passwords in settings/passwords (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months 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
OLDNEW
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
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
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
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
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 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698