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

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

Issue 1318523011: [Password Manager] Copiable username and origin. Linkable origin elided from the left. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Copiable username and origin in css. Linkable origin elided from the left. Created 5 years, 2 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 List = cr.ui.List; 9 /** @const */ var List = cr.ui.List;
10 10
11 /** @const */ var URL_DATA_INDEX = 0; 11 /** @const */ var URL_DATA_INDEX = 0;
12 /** @const */ var USERNAME_DATA_INDEX = 1; 12 /** @const */ var SHOWN_URL_DATA_INDEX = 1;
13 /** @const */ var PASSWORD_DATA_INDEX = 2; 13 /** @const */ var IS_URL_SECURE_DATA_INDEX = 2;
14 /** @const */ var FEDERATION_DATA_INDEX = 3; 14 /** @const */ var USERNAME_DATA_INDEX = 3;
15 /** @const */ var ORIGINAL_DATA_INDEX = 4; 15 /** @const */ var PASSWORD_DATA_INDEX = 4;
16 /** @const */ var FEDERATION_DATA_INDEX = 5;
17 /** @const */ var ORIGINAL_DATA_INDEX = 6;
16 18
17 /** 19 /**
18 * Creates a new passwords list item. 20 * Creates a new passwords list item.
19 * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this 21 * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this
20 * item. 22 * item.
21 * @param {Array} entry An array of the form [url, username, password, 23 * @param {Array} entry An array of the form [url, username, password,
22 * federation]. When the list has been filtered, a fifth element [index] 24 * federation]. When the list has been filtered, a fifth element [index]
23 * may be present. 25 * may be present.
24 * @param {boolean} showPasswords If true, add a button to the element to 26 * @param {boolean} showPasswords If true, add a button to the element to
25 * allow the user to reveal the saved password. 27 * allow the user to reveal the saved password.
26 * @constructor 28 * @constructor
27 * @extends {options.DeletableItem} 29 * @extends {options.DeletableItem}
28 */ 30 */
29 function PasswordListItem(dataModel, entry, showPasswords) { 31 function PasswordListItem(dataModel, entry, showPasswords) {
30 var el = cr.doc.createElement('div'); 32 var el = cr.doc.createElement('div');
31 el.dataItem = entry; 33 el.dataItem = entry;
32 el.dataModel = dataModel; 34 el.dataModel = dataModel;
33 el.__proto__ = PasswordListItem.prototype; 35 el.__proto__ = PasswordListItem.prototype;
34 el.showPasswords_ = showPasswords; 36 el.showPasswords_ = showPasswords;
35 el.decorate(); 37 el.decorate();
36 38
37 return el; 39 return el;
38 } 40 }
39 41
40 PasswordListItem.prototype = { 42 PasswordListItem.prototype = {
41 __proto__: DeletableItem.prototype, 43 __proto__: DeletableItem.prototype,
42 44
45
43 /** @override */ 46 /** @override */
44 decorate: function() { 47 decorate: function() {
45 DeletableItem.prototype.decorate.call(this); 48 DeletableItem.prototype.decorate.call(this);
46 49
47 // The URL of the site. 50 // The URL of the site.
48 var urlLabel = this.ownerDocument.createElement('div'); 51 var urlDiv = this.ownerDocument.createElement('div');
49 urlLabel.classList.add('favicon-cell'); 52 urlDiv.classList.add('favicon-cell');
Evan Stade 2015/09/29 18:06:53 urlDiv.className = 'favicon-cell left-elided-url u
kolos1 2015/09/29 18:29:01 Done.
50 urlLabel.classList.add('weakrtl'); 53 urlDiv.classList.add('left-elided-url');
51 urlLabel.classList.add('url'); 54 urlDiv.classList.add('url');
52 urlLabel.setAttribute('title', this.url); 55 urlDiv.setAttribute('title', this.url);
53 urlLabel.textContent = this.url; 56 var urlLink = this.ownerDocument.createElement('a');
57 urlLink.href = this.url;
58 urlLink.textContent = this.shownUrl.split('').reverse().join('');
59 urlDiv.appendChild(urlLink);
54 60
55 // The favicon URL is prefixed with "origin/", which essentially removes 61 // The favicon URL is prefixed with "origin/", which essentially removes
56 // the URL path past the top-level domain and ensures that a scheme (e.g., 62 // the URL path past the top-level domain and ensures that a scheme (e.g.,
57 // http) is being used. This ensures that the favicon returned is the 63 // http) is being used. This ensures that the favicon returned is the
58 // default favicon for the domain and that the URL has a scheme if none 64 // default favicon for the domain and that the URL has a scheme if none
59 // is present in the password manager. 65 // is present in the password manager.
60 urlLabel.style.backgroundImage = getFaviconImageSet( 66 if (this.isUrlSecure) {
61 'origin/' + this.url, 16); 67 urlDiv.style.backgroundImage = getFaviconImageSet(
62 this.contentElement.appendChild(urlLabel); 68 'origin/' + this.url, 16);
69 }
70 this.contentElement.appendChild(urlDiv);
63 71
64 // The stored username. 72 // The stored username.
65 var usernameLabel = this.ownerDocument.createElement('div'); 73 var usernameDiv = this.ownerDocument.createElement('div');
66 usernameLabel.className = 'name'; 74 usernameDiv.className = 'name';
67 usernameLabel.textContent = this.username; 75 //usernameDiv.textContent = this.username;
68 usernameLabel.title = this.username; 76 usernameDiv.title = this.username;
69 this.contentElement.appendChild(usernameLabel); 77 this.contentElement.appendChild(usernameDiv);
78 var usernameInput = this.ownerDocument.createElement('input');
79 usernameInput.type = 'text';
Evan Stade 2015/09/29 18:06:53 one other good way of doing this is to use html te
80 usernameInput.className = 'inactive-item';
81 usernameInput.readOnly = true;
82 usernameInput.value = this.username;
83 usernameDiv.appendChild(usernameInput);
84 this.usernameField = usernameInput;
70 85
71 if (this.federation) { 86 if (this.federation) {
72 // The federation. 87 // The federation.
73 var federationDiv = this.ownerDocument.createElement('div'); 88 var federationDiv = this.ownerDocument.createElement('div');
74 federationDiv.className = 'federation'; 89 federationDiv.className = 'federation';
75 federationDiv.textContent = this.federation; 90 federationDiv.textContent = this.federation;
76 this.contentElement.appendChild(federationDiv); 91 this.contentElement.appendChild(federationDiv);
77 } else { 92 } else {
78 // The stored password. 93 // The stored password.
79 var passwordInputDiv = this.ownerDocument.createElement('div'); 94 var passwordInputDiv = this.ownerDocument.createElement('div');
80 passwordInputDiv.className = 'password'; 95 passwordInputDiv.className = 'password';
81 96
82 // The password input field. 97 // The password input field.
83 var passwordInput = this.ownerDocument.createElement('input'); 98 var passwordInput = this.ownerDocument.createElement('input');
84 passwordInput.type = 'password'; 99 passwordInput.type = 'password';
85 passwordInput.className = 'inactive-password'; 100 passwordInput.className = 'inactive-item';
86 passwordInput.readOnly = true; 101 passwordInput.readOnly = true;
87 passwordInput.value = this.showPasswords_ ? this.password : '********'; 102 passwordInput.value = this.showPasswords_ ? this.password : '********';
88 passwordInputDiv.appendChild(passwordInput); 103 passwordInputDiv.appendChild(passwordInput);
89 var deletableItem = this; 104 var deletableItem = this;
90 passwordInput.addEventListener('focus', function() { 105 passwordInput.addEventListener('focus', function() {
91 deletableItem.handleFocus(); 106 deletableItem.handleFocus();
92 }); 107 });
93 this.passwordField = passwordInput; 108 this.passwordField = passwordInput;
94 this.setFocusable_(false); 109 this.setFocusable_(false);
95 110
(...skipping 11 matching lines...) Expand all
107 event.stopPropagation(); 122 event.stopPropagation();
108 }, false); 123 }, false);
109 button.addEventListener('focus', function() { 124 button.addEventListener('focus', function() {
110 deletableItem.handleFocus(); 125 deletableItem.handleFocus();
111 }); 126 });
112 passwordInputDiv.appendChild(button); 127 passwordInputDiv.appendChild(button);
113 this.passwordShowButton = button; 128 this.passwordShowButton = button;
114 } 129 }
115 this.contentElement.appendChild(passwordInputDiv); 130 this.contentElement.appendChild(passwordInputDiv);
116 } 131 }
117
118 }, 132 },
119 133
120 /** @override */ 134 /** @override */
121 selectionChanged: function() { 135 selectionChanged: function() {
122 var input = this.passwordField; 136 var usernameInput = this.usernameField;
137 var passwordInput = this.passwordField;
123 var button = this.passwordShowButton; 138 var button = this.passwordShowButton;
124 // The button doesn't exist when passwords can't be shown. 139 // The button doesn't exist when passwords can't be shown.
125 if (!button) 140 if (!button)
126 return; 141 return;
127 142
128 if (this.selected) { 143 if (this.selected) {
129 input.classList.remove('inactive-password'); 144 usernameInput.classList.remove('inactive-item');
145 passwordInput.classList.remove('inactive-item');
130 this.setFocusable_(true); 146 this.setFocusable_(true);
131 button.hidden = false; 147 button.hidden = false;
132 input.focus(); 148 passwordInput.focus();
133 } else { 149 } else {
134 input.classList.add('inactive-password'); 150 usernameInput.classList.add('inactive-item');
151 passwordInput.classList.add('inactive-item');
135 this.setFocusable_(false); 152 this.setFocusable_(false);
136 button.hidden = true; 153 button.hidden = true;
137 } 154 }
138 }, 155 },
139 156
140 /** 157 /**
141 * Set the focusability of this row. 158 * Set the focusability of this row.
142 * @param {boolean} focusable 159 * @param {boolean} focusable
143 * @private 160 * @private
144 */ 161 */
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 * @type {string} 216 * @type {string}
200 */ 217 */
201 get url() { 218 get url() {
202 return this.dataItem[URL_DATA_INDEX]; 219 return this.dataItem[URL_DATA_INDEX];
203 }, 220 },
204 set url(url) { 221 set url(url) {
205 this.dataItem[URL_DATA_INDEX] = url; 222 this.dataItem[URL_DATA_INDEX] = url;
206 }, 223 },
207 224
208 /** 225 /**
226 * Get and set the shown url for the entry.
227 * @type {string}
228 */
229 get shownUrl() {
230 return this.dataItem[SHOWN_URL_DATA_INDEX];
231 },
232 set shownUrl(shownUrl) {
233 this.dataItem[SHOWN_URL_DATA_INDEX] = shownUrl;
234 },
235
236 /**
237 * Get and set whether the origin uses secure scheme.
238 * @type {boolean}
239 */
240 get isUrlSecure() {
241 return this.dataItem[IS_URL_SECURE_DATA_INDEX];
242 },
243 set isUrlSecure(isUrlSecure) {
244 this.dataItem[IS_URL_SECURE_DATA_INDEX] = isUrlSecure;
245 },
246
247 /**
209 * Get and set the username for the entry. 248 * Get and set the username for the entry.
210 * @type {string} 249 * @type {string}
211 */ 250 */
212 get username() { 251 get username() {
213 return this.dataItem[USERNAME_DATA_INDEX]; 252 return this.dataItem[USERNAME_DATA_INDEX];
214 }, 253 },
215 set username(username) { 254 set username(username) {
216 this.dataItem[USERNAME_DATA_INDEX] = username; 255 this.dataItem[USERNAME_DATA_INDEX] = username;
217 }, 256 },
218 257
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 PasswordExceptionsListItem.prototype = { 296 PasswordExceptionsListItem.prototype = {
258 __proto__: DeletableItem.prototype, 297 __proto__: DeletableItem.prototype,
259 298
260 /** 299 /**
261 * Call when an element is decorated as a list item. 300 * Call when an element is decorated as a list item.
262 */ 301 */
263 decorate: function() { 302 decorate: function() {
264 DeletableItem.prototype.decorate.call(this); 303 DeletableItem.prototype.decorate.call(this);
265 304
266 // The URL of the site. 305 // The URL of the site.
267 var urlLabel = this.ownerDocument.createElement('div'); 306 var urlDiv = this.ownerDocument.createElement('div');
268 urlLabel.className = 'url'; 307 urlDiv.className = 'url';
269 urlLabel.classList.add('favicon-cell'); 308 urlDiv.classList.add('favicon-cell');
270 urlLabel.classList.add('weakrtl'); 309 urlDiv.classList.add('left-elided-url');
271 urlLabel.textContent = this.url; 310 urlDiv.setAttribute('title', this.url);
311 var urlLink = this.ownerDocument.createElement('a');
312 urlLink.href = this.url;
313 urlLink.textContent = this.shownUrl.split('').reverse().join('');
314 urlDiv.appendChild(urlLink);
272 315
273 // The favicon URL is prefixed with "origin/", which essentially removes 316 // The favicon URL is prefixed with "origin/", which essentially removes
274 // the URL path past the top-level domain and ensures that a scheme (e.g., 317 // the URL path past the top-level domain and ensures that a scheme (e.g.,
275 // http) is being used. This ensures that the favicon returned is the 318 // http) is being used. This ensures that the favicon returned is the
276 // default favicon for the domain and that the URL has a scheme if none 319 // default favicon for the domain and that the URL has a scheme if none
277 // is present in the password manager. 320 // is present in the password manager.
278 urlLabel.style.backgroundImage = getFaviconImageSet( 321 if (this.isUrlSecure) {
279 'origin/' + this.url, 16); 322 urlDiv.style.backgroundImage = getFaviconImageSet(
280 this.contentElement.appendChild(urlLabel); 323 'origin/' + this.url, 16);
324 }
325 this.contentElement.appendChild(urlDiv);
281 }, 326 },
282 327
283 /** 328 /**
284 * Get the url for the entry. 329 * Get the url for the entry.
285 * @type {string} 330 * @type {string}
286 */ 331 */
287 get url() { 332 get url() {
288 return this.dataItem; 333 return this.dataItem[URL_DATA_INDEX];
289 }, 334 },
290 set url(url) { 335 set url(url) {
291 this.dataItem = url; 336 this.dataItem[URL_DATA_INDEX] = url;
337 },
338
339 /**
340 * Get and set the shown url for the entry.
341 * @type {string}
342 */
343 get shownUrl() {
344 return this.dataItem[SHOWN_URL_DATA_INDEX];
345 },
346 set shownUrl(shownUrl) {
347 this.dataItem[SHOWN_URL_DATA_INDEX] = shownUrl;
348 },
349
350 /**
351 * Get and set whether the origin uses secure scheme.
352 * @type {boolean}
353 */
354 get isUrlSecure() {
355 return this.dataItem[IS_URL_SECURE_DATA_INDEX];
356 },
357 set isUrlSecure(isUrlSecure) {
358 this.dataItem[IS_URL_SECURE_DATA_INDEX] = isUrlSecure;
292 }, 359 },
293 }; 360 };
294 361
295 /** 362 /**
296 * Create a new passwords list. 363 * Create a new passwords list.
297 * @constructor 364 * @constructor
298 * @extends {options.DeletableItemList} 365 * @extends {options.DeletableItemList}
299 */ 366 */
300 var PasswordsList = cr.ui.define('list'); 367 var PasswordsList = cr.ui.define('list');
301 368
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 get length() { 466 get length() {
400 return this.dataModel.length; 467 return this.dataModel.length;
401 }, 468 },
402 }; 469 };
403 470
404 return { 471 return {
405 PasswordListItem: PasswordListItem, 472 PasswordListItem: PasswordListItem,
406 PasswordExceptionsListItem: PasswordExceptionsListItem, 473 PasswordExceptionsListItem: PasswordExceptionsListItem,
407 PasswordsList: PasswordsList, 474 PasswordsList: PasswordsList,
408 PasswordExceptionsList: PasswordExceptionsList, 475 PasswordExceptionsList: PasswordExceptionsList,
476 URL_DATA_INDEX: URL_DATA_INDEX,
477 SHOWN_URL_DATA_INDEX: SHOWN_URL_DATA_INDEX,
478 IS_URL_SECURE_DATA_INDEX: IS_URL_SECURE_DATA_INDEX,
479 USERNAME_DATA_INDEX: USERNAME_DATA_INDEX,
480 PASSWORD_DATA_INDEX: PASSWORD_DATA_INDEX,
481 FEDERATION_DATA_INDEX: FEDERATION_DATA_INDEX,
482 ORIGINAL_DATA_INDEX: ORIGINAL_DATA_INDEX
409 }; 483 };
410 }); 484 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698