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

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

Issue 1615653005: [Password manager] Human readable origins for Android credentials on chrome://settings/passwords (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added a space to (Android) in generated_resources.grd. Removed CSS class android-uri-suffix Created 4 years, 8 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 // The following constants should be synchronized with the constants in 11 // The following constants should be synchronized with the constants in
12 // chrome/browser/ui/webui/options/password_manager_handler.cc. 12 // chrome/browser/ui/webui/options/password_manager_handler.cc.
13 /** @const */ var ORIGIN_FIELD = 'origin'; 13 /** @const */ var URL_FIELD = 'url';
14 /** @const */ var SHOWN_URL_FIELD = 'shownUrl'; 14 /** @const */ var SHOWN_ORIGIN_FIELD = 'shownOrigin';
15 /** @const */ var IS_ANDROID_URI_FIELD = 'isAndroidUri'; 15 /** @const */ var IS_ANDROID_URI_FIELD = 'isAndroidUri';
16 /** @const */ var IS_CLICKABLE_FIELD = 'isClickable';
16 /** @const */ var IS_SECURE_FIELD = 'isSecure'; 17 /** @const */ var IS_SECURE_FIELD = 'isSecure';
17 /** @const */ var USERNAME_FIELD = 'username'; 18 /** @const */ var USERNAME_FIELD = 'username';
18 /** @const */ var PASSWORD_FIELD = 'password'; 19 /** @const */ var PASSWORD_FIELD = 'password';
19 /** @const */ var FEDERATION_FIELD = 'federation'; 20 /** @const */ var FEDERATION_FIELD = 'federation';
20 /** @const */ var ORIGINAL_INDEX_FIELD = 'index'; 21 /** @const */ var ORIGINAL_INDEX_FIELD = 'index';
21 22
22 /** 23 /**
23 * Creates a new passwords list item. 24 * Creates a new passwords list item.
24 * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this 25 * @param {cr.ui.ArrayDataModel} dataModel The data model that contains this
25 * item. 26 * item.
26 * @param {Object} entry A dictionary of data on new list item. When the 27 * @param {Object} entry A dictionary of data on new list item. When the
27 * list has been filtered, one more element [index] may be present. 28 * list has been filtered, one more element [index] may be present.
28 * @param {boolean} showPasswords If true, add a button to the element to 29 * @param {boolean} showPasswords If true, add a button to the element to
29 * allow the user to reveal the saved password. 30 * allow the user to reveal the saved password.
30 * @constructor 31 * @constructor
31 * @extends {options.DeletableItem} 32 * @extends {options.DeletableItem}
32 */ 33 */
33 function PasswordListItem(dataModel, entry, showPasswords) { 34 function PasswordListItem(dataModel, entry, showPasswords) {
34 var el = cr.doc.createElement('div'); 35 var el = cr.doc.createElement('div');
35 el.dataItem = entry; 36 el.dataItem = entry;
36 el.dataModel = dataModel; 37 el.dataModel = dataModel;
37 el.__proto__ = PasswordListItem.prototype; 38 el.__proto__ = PasswordListItem.prototype;
38 el.showPasswords_ = showPasswords; 39 el.showPasswords_ = showPasswords;
39 el.decorate(); 40 el.decorate();
40 41
41 return el; 42 return el;
42 } 43 }
43 44
44 /** 45 /**
45 * Returns title for password's origin. If the origin is Android URI, returns 46 * Returns title for password's origin. If the origin is not clickable,
46 * the origin as it is. Removes the scheme if the url is insecure and removes 47 * returns the origin as it is. For clickable origins, removes the scheme if
47 * trailing punctuation symbols. 48 * the url is insecure and removes trailing punctuation symbols.
48 * @param {Object} item A dictionary of data on the list item. 49 * @param {Object} item A dictionary of data on the list item.
49 * @return {string} The title for password's origin. 50 * @return {string} The title for password's origin.
50 */ 51 */
51 function getTitleForPasswordOrigin(item) { 52 function getTitleForPasswordOrigin(item) {
52 var title = item.url; 53 var title = item.url;
53 if (item.isAndroidUri) 54 if (!item.isClickable)
54 return title; 55 return title;
55 if (!item.isSecure) { 56 if (!item.isSecure) {
56 var ind = title.indexOf('://'); 57 var ind = title.indexOf('://');
57 if (ind >= 0) { 58 if (ind >= 0) {
58 title = title.substring(ind + 3); 59 title = title.substring(ind + 3);
59 } 60 }
60 } 61 }
61 return title; 62 return title;
62 } 63 }
63 64
64 /** 65 /**
65 * Helper function that creates an HTML element for displaying the origin of 66 * Helper function that creates an HTML element for displaying the link to
66 * saved password. 67 * the origin of saved password.
67 * @param {Object} item A dictionary of data on the list item. 68 * @param {Object} item A dictionary of data on the list item.
68 * @param {Element} urlDiv div-element that will enclose the created 69 * @param {Element} urlDiv div-element that will enclose the created
69 * element. 70 * element.
70 * @return {Element} The element for displaying password origin. 71 * @return {Element} The element for displaying the link to the origin.
71 */ 72 */
72 function createUrlLink(item, urlDiv) { 73 function createUrlLink(item, urlDiv) {
73 var urlLink; 74 var urlLink;
74 if (!item.isAndroidUri) { 75 if (item.isClickable) {
75 urlLink = item.ownerDocument.createElement('a'); 76 urlLink = item.ownerDocument.createElement('a');
76 urlLink.href = item.url; 77 urlLink.href = item.url;
77 urlLink.setAttribute('target', '_blank'); 78 urlLink.setAttribute('target', '_blank');
78 urlLink.dir = 'ltr'; 79 urlLink.dir = 'ltr';
79 } else { 80 } else {
80 urlLink = item.ownerDocument.createElement('span'); 81 urlLink = item.ownerDocument.createElement('span');
81 } 82 }
82 urlLink.textContent = item.shownUrl; 83 urlLink.textContent = item.shownOrigin;
83 urlLink.addEventListener('focus', function() { 84 urlLink.addEventListener('focus', function() {
84 item.handleFocus(); 85 item.handleFocus();
85 }.bind(item)); 86 }.bind(item));
86 return urlLink; 87 return urlLink;
87 } 88 }
88 89
90 /**
91 * Helper function that creates an HTML element for displaying the origin of
92 * saved password. It also sets some properties in |item|.
93 * @param {Object} item A dictionary of data on the list item.
94 * @return {Element} The element for displaying the origin of saved password.
95 */
96 function createUrlDiv(item) {
97 var urlDiv = cr.doc.createElement('div');
98 urlDiv.className = 'favicon-cell url';
99 urlDiv.setAttribute('title', getTitleForPasswordOrigin(item));
100 urlDiv.style.backgroundImage = getFaviconImageSet(
101 'origin/' + item.url, 16);
102
103 item.urlLink = createUrlLink(item, urlDiv);
104 urlDiv.appendChild(item.urlLink);
105
106 if (item.isAndroidUri && item.isClickable) {
107 var androidUriSuffix = cr.doc.createElement('span');
Evan Stade 2016/03/30 21:52:03 nit: no need for this local var, you can just assi
108 androidUriSuffix.textContent = loadTimeData.getString('androidUriSuffix');
109 item.androidUriSuffix = androidUriSuffix;
110 urlDiv.appendChild(androidUriSuffix);
111 }
112
113 item.urlDiv = urlDiv;
114 return urlDiv;
115 }
116
89 PasswordListItem.prototype = { 117 PasswordListItem.prototype = {
90 __proto__: DeletableItem.prototype, 118 __proto__: DeletableItem.prototype,
91 119
92 /** @override */ 120 /** @override */
93 decorate: function() { 121 decorate: function() {
94 DeletableItem.prototype.decorate.call(this); 122 DeletableItem.prototype.decorate.call(this);
95 123
96 // The URL of the site. 124 // The URL of the site.
97 var urlDiv = this.ownerDocument.createElement('div'); 125 this.contentElement.appendChild(createUrlDiv(this));
98 urlDiv.className = 'favicon-cell url';
99 urlDiv.setAttribute('title', getTitleForPasswordOrigin(this));
100 urlDiv.style.backgroundImage = getFaviconImageSet(
101 'origin/' + this.url, 16);
102
103 this.urlLink = createUrlLink(this, urlDiv);
104 urlDiv.appendChild(this.urlLink);
105
106 this.urlDiv = urlDiv;
107 this.contentElement.appendChild(urlDiv);
108 126
109 // The stored username. 127 // The stored username.
110 var usernameDiv = this.ownerDocument.createElement('div'); 128 var usernameDiv = this.ownerDocument.createElement('div');
111 usernameDiv.className = 'name'; 129 usernameDiv.className = 'name';
112 usernameDiv.title = this.username; 130 usernameDiv.title = this.username;
113 this.contentElement.appendChild(usernameDiv); 131 this.contentElement.appendChild(usernameDiv);
114 var usernameInput = this.ownerDocument.createElement('input'); 132 var usernameInput = this.ownerDocument.createElement('input');
115 usernameInput.type = 'text'; 133 usernameInput.type = 'text';
116 usernameInput.className = 'inactive-item'; 134 usernameInput.className = 'inactive-item';
117 usernameInput.readOnly = true; 135 usernameInput.readOnly = true;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 onClick_: function(event) { 269 onClick_: function(event) {
252 if (this.passwordField.type == 'password') { 270 if (this.passwordField.type == 'password') {
253 // After the user is authenticated, showPassword() will be called. 271 // After the user is authenticated, showPassword() will be called.
254 PasswordManager.requestShowPassword(this.getOriginalIndex_()); 272 PasswordManager.requestShowPassword(this.getOriginalIndex_());
255 } else { 273 } else {
256 this.hidePassword(); 274 this.hidePassword();
257 } 275 }
258 }, 276 },
259 277
260 /** 278 /**
261 * Get and set the URL for the entry. 279 * Get the URL for the entry.
262 * @type {string} 280 * @type {string}
263 */ 281 */
264 get url() { 282 get url() {
265 return this.dataItem[ORIGIN_FIELD]; 283 return this.dataItem[URL_FIELD];
266 },
267 set url(url) {
268 this.dataItem[ORIGIN_FIELD] = url;
269 }, 284 },
270 285
271 /** 286 /**
272 * Get and set the shown url for the entry. 287 * Get the shown origin for the entry.
273 * @type {string} 288 * @type {string}
274 */ 289 */
275 get shownUrl() { 290 get shownOrigin() {
276 return this.dataItem[SHOWN_URL_FIELD]; 291 return this.dataItem[SHOWN_ORIGIN_FIELD];
277 },
278 set shownUrl(shownUrl) {
279 this.dataItem[SHOWN_URL_FIELD] = shownUrl;
280 }, 292 },
281 293
282 /** 294 /**
283 * Get and set whether the origin is Android URI. 295 * Get whether the origin is Android URI.
284 * @type {boolean} 296 * @type {boolean}
285 */ 297 */
286 get isAndroidUri() { 298 get isAndroidUri() {
287 return this.dataItem[IS_ANDROID_URI_FIELD]; 299 return this.dataItem[IS_ANDROID_URI_FIELD];
288 }, 300 },
289 set isAndroidUri(isAndroidUri) { 301
290 this.dataItem[IS_ANDROID_URI_FIELD] = isAndroidUri; 302 /**
303 * Get whether the origin is clickable.
304 * @type {boolean}
305 */
306 get isClickable() {
307 return this.dataItem[IS_CLICKABLE_FIELD];
291 }, 308 },
292 309
293 /** 310 /**
294 * Get and set whether the origin uses secure scheme. 311 * Get whether the origin uses secure scheme.
295 * @type {boolean} 312 * @type {boolean}
296 */ 313 */
297 get isSecure() { 314 get isSecure() {
298 return this.dataItem[IS_SECURE_FIELD]; 315 return this.dataItem[IS_SECURE_FIELD];
299 }, 316 },
300 set isSecure(isSecure) {
301 this.dataItem[IS_SECURE_FIELD] = isSecure;
302 },
303 317
304 /** 318 /**
305 * Get and set the username for the entry. 319 * Get the username for the entry.
306 * @type {string} 320 * @type {string}
307 */ 321 */
308 get username() { 322 get username() {
309 return this.dataItem[USERNAME_FIELD]; 323 return this.dataItem[USERNAME_FIELD];
310 }, 324 },
311 set username(username) {
312 this.dataItem[USERNAME_FIELD] = username;
313 },
314 325
315 /** 326 /**
316 * Get and set the password for the entry. 327 * Get the password for the entry.
317 * @type {string} 328 * @type {string}
318 */ 329 */
319 get password() { 330 get password() {
320 return this.dataItem[PASSWORD_FIELD]; 331 return this.dataItem[PASSWORD_FIELD];
321 }, 332 },
322 set password(password) {
323 this.dataItem[PASSWORD_FIELD] = password;
324 },
325 333
326 /** 334 /**
327 * Get and set the federation for the entry. 335 * Get the federation for the entry.
328 * @type {string} 336 * @type {string}
329 */ 337 */
330 get federation() { 338 get federation() {
331 return this.dataItem[FEDERATION_FIELD]; 339 return this.dataItem[FEDERATION_FIELD];
332 }, 340 },
333 set federation(federation) {
334 this.dataItem[FEDERATION_FIELD] = federation;
335 },
336 }; 341 };
337 342
338 /** 343 /**
339 * Creates a new PasswordExceptions list item. 344 * Creates a new PasswordExceptions list item.
340 * @param {Object} entry A dictionary of data on new list item. 345 * @param {Object} entry A dictionary of data on new list item.
341 * @constructor 346 * @constructor
342 * @extends {options.DeletableItem} 347 * @extends {options.DeletableItem}
343 */ 348 */
344 function PasswordExceptionsListItem(entry) { 349 function PasswordExceptionsListItem(entry) {
345 var el = cr.doc.createElement('div'); 350 var el = cr.doc.createElement('div');
346 el.dataItem = entry; 351 el.dataItem = entry;
347 el.__proto__ = PasswordExceptionsListItem.prototype; 352 el.__proto__ = PasswordExceptionsListItem.prototype;
348 el.decorate(); 353 el.decorate();
349 354
350 return el; 355 return el;
351 } 356 }
352 357
353 PasswordExceptionsListItem.prototype = { 358 PasswordExceptionsListItem.prototype = {
354 __proto__: DeletableItem.prototype, 359 __proto__: DeletableItem.prototype,
355 360
356 /** 361 /**
357 * Call when an element is decorated as a list item. 362 * Call when an element is decorated as a list item.
358 */ 363 */
359 decorate: function() { 364 decorate: function() {
360 DeletableItem.prototype.decorate.call(this); 365 DeletableItem.prototype.decorate.call(this);
361 366
362 // The URL of the site. 367 // The URL of the site.
363 var urlDiv = this.ownerDocument.createElement('div'); 368 this.contentElement.appendChild(createUrlDiv(this));
364 urlDiv.className = 'favicon-cell url';
365 urlDiv.setAttribute('title', getTitleForPasswordOrigin(this));
366 urlDiv.style.backgroundImage = getFaviconImageSet(
367 'origin/' + this.url, 16);
368
369 this.urlLink = createUrlLink(this, urlDiv);
370 urlDiv.appendChild(this.urlLink);
371
372 this.urlDiv = urlDiv;
373 this.contentElement.appendChild(urlDiv);
374 }, 369 },
375 370
376 /** @override */ 371 /** @override */
377 selectionChanged: function() { 372 selectionChanged: function() {
378 if (this.selected) { 373 if (this.selected) {
379 this.setFocusable_(true); 374 this.setFocusable_(true);
380 this.urlLink.focus(); 375 this.urlLink.focus();
381 } else { 376 } else {
382 this.setFocusable_(false); 377 this.setFocusable_(false);
383 } 378 }
384 }, 379 },
385 380
386 /** 381 /**
387 * Set the focusability of this row. 382 * Set the focusability of this row.
388 * @param {boolean} focusable 383 * @param {boolean} focusable
389 * @private 384 * @private
390 */ 385 */
391 setFocusable_: function(focusable) { 386 setFocusable_: function(focusable) {
392 var tabIndex = focusable ? 0 : -1; 387 var tabIndex = focusable ? 0 : -1;
393 this.urlLink.tabIndex = tabIndex; 388 this.urlLink.tabIndex = tabIndex;
394 this.closeButtonElement.tabIndex = tabIndex; 389 this.closeButtonElement.tabIndex = tabIndex;
395 }, 390 },
396 391
397 /** 392 /**
398 * Get the url for the entry. 393 * Get the url for the entry.
399 * @type {string} 394 * @type {string}
400 */ 395 */
401 get url() { 396 get url() {
402 return this.dataItem[ORIGIN_FIELD]; 397 return this.dataItem[URL_FIELD];
403 },
404 set url(url) {
405 this.dataItem[ORIGIN_FIELD] = url;
406 }, 398 },
407 399
408 /** 400 /**
409 * Get and set the shown url for the entry. 401 * Get the shown origin for the entry.
410 * @type {string} 402 * @type {string}
411 */ 403 */
412 get shownUrl() { 404 get shownOrigin() {
413 return this.dataItem[SHOWN_URL_FIELD]; 405 return this.dataItem[SHOWN_ORIGIN_FIELD];
414 },
415 set shownUrl(shownUrl) {
416 this.dataItem[SHOWN_URL_FIELD] = shownUrl;
417 }, 406 },
418 407
419 /** 408 /**
420 * Get and set whether the origin is Android URI. 409 * Get whether the origin is Android URI.
421 * @type {boolean} 410 * @type {boolean}
422 */ 411 */
423 get isAndroidUri() { 412 get isAndroidUri() {
424 return this.dataItem[IS_ANDROID_URI_FIELD]; 413 return this.dataItem[IS_ANDROID_URI_FIELD];
425 }, 414 },
426 set isAndroidUri(isAndroidUri) { 415
427 this.dataItem[IS_ANDROID_URI_FIELD] = isAndroidUri; 416 /**
417 * Get whether the origin is clickable.
418 * @type {boolean}
419 */
420 get isClickable() {
421 return this.dataItem[IS_CLICKABLE_FIELD];
428 }, 422 },
429 423
430 /** 424 /**
431 * Get and set whether the origin uses secure scheme. 425 * Get whether the origin uses secure scheme.
432 * @type {boolean} 426 * @type {boolean}
433 */ 427 */
434 get isSecure() { 428 get isSecure() {
435 return this.dataItem[IS_SECURE_FIELD]; 429 return this.dataItem[IS_SECURE_FIELD];
436 }, 430 },
437 set isSecure(isSecure) {
438 this.dataItem[IS_SECURE_FIELD] = isSecure;
439 },
440 }; 431 };
441 432
442 /** 433 /**
443 * Create a new passwords list. 434 * Create a new passwords list.
444 * @constructor 435 * @constructor
445 * @extends {options.DeletableItemList} 436 * @extends {options.DeletableItemList}
446 */ 437 */
447 var PasswordsList = cr.ui.define('list'); 438 var PasswordsList = cr.ui.define('list');
448 439
449 PasswordsList.prototype = { 440 PasswordsList.prototype = {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 get length() { 537 get length() {
547 return this.dataModel.length; 538 return this.dataModel.length;
548 }, 539 },
549 }; 540 };
550 541
551 return { 542 return {
552 PasswordListItem: PasswordListItem, 543 PasswordListItem: PasswordListItem,
553 PasswordExceptionsListItem: PasswordExceptionsListItem, 544 PasswordExceptionsListItem: PasswordExceptionsListItem,
554 PasswordsList: PasswordsList, 545 PasswordsList: PasswordsList,
555 PasswordExceptionsList: PasswordExceptionsList, 546 PasswordExceptionsList: PasswordExceptionsList,
556 ORIGIN_FIELD: ORIGIN_FIELD, 547 URL_FIELD: URL_FIELD,
557 SHOWN_URL_FIELD: SHOWN_URL_FIELD, 548 SHOWN_ORIGIN_FIELD: SHOWN_ORIGIN_FIELD,
549 IS_ANDROID_URI_FIELD: IS_ANDROID_URI_FIELD,
550 IS_CLICKABLE_FIELD: IS_CLICKABLE_FIELD,
558 IS_SECURE_FIELD: IS_SECURE_FIELD, 551 IS_SECURE_FIELD: IS_SECURE_FIELD,
559 USERNAME_FIELD: USERNAME_FIELD, 552 USERNAME_FIELD: USERNAME_FIELD,
560 PASSWORD_FIELD: PASSWORD_FIELD, 553 PASSWORD_FIELD: PASSWORD_FIELD,
561 FEDERATION_FIELD: FEDERATION_FIELD, 554 FEDERATION_FIELD: FEDERATION_FIELD,
562 ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD 555 ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD
563 }; 556 };
564 }); 557 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/options/password_manager.js ('k') | chrome/browser/ui/passwords/password_manager_presenter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698