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

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: Removed unused setters in PasswordExceptionsListItem and PasswordListItem. Created 4 years, 9 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 that is appended to the
Evan Stade 2016/03/24 16:50:36 not sure if helper is useful. Just inline it?
kolos1 2016/03/29 09:03:03 Done.
92 * clickable origins of Android credentials.
93 * @return {Element} The element to append Android clickable origins.
94 */
95 function createAndroidUriSuffix() {
96 var androidUriSuffix = cr.doc.createElement('span');
97 androidUriSuffix.className = 'android-uri-suffix';
98 androidUriSuffix.textContent = loadTimeData.getString('androidUriSuffix');
99 return androidUriSuffix;
100 }
101
102 /**
103 * Helper function that creates an HTML element for displaying the origin of
104 * saved password. It also sets some properties in |item|.
105 * @param {Object} item A dictionary of data on the list item.
106 * @return {Element} The element for displaying the origin of saved password.
107 */
108 function createUrlDiv(item) {
109 var urlDiv = cr.doc.createElement('div');
110 urlDiv.className = 'favicon-cell url';
111 urlDiv.setAttribute('title', getTitleForPasswordOrigin(item));
112 urlDiv.style.backgroundImage = getFaviconImageSet(
113 'origin/' + item.url, 16);
114
115 item.urlLink = createUrlLink(item, urlDiv);
116 urlDiv.appendChild(item.urlLink);
117
118 if (item.isAndroidUri && item.isClickable) {
119 item.androidUriSuffix = createAndroidUriSuffix();
120 urlDiv.appendChild(item.androidUriSuffix);
121 }
122
123 item.urlDiv = urlDiv;
124 return urlDiv;
125 }
126
89 PasswordListItem.prototype = { 127 PasswordListItem.prototype = {
90 __proto__: DeletableItem.prototype, 128 __proto__: DeletableItem.prototype,
91 129
92 /** @override */ 130 /** @override */
93 decorate: function() { 131 decorate: function() {
94 DeletableItem.prototype.decorate.call(this); 132 DeletableItem.prototype.decorate.call(this);
95 133
96 // The URL of the site. 134 // The URL of the site.
97 var urlDiv = this.ownerDocument.createElement('div'); 135 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 136
109 // The stored username. 137 // The stored username.
110 var usernameDiv = this.ownerDocument.createElement('div'); 138 var usernameDiv = this.ownerDocument.createElement('div');
111 usernameDiv.className = 'name'; 139 usernameDiv.className = 'name';
112 usernameDiv.title = this.username; 140 usernameDiv.title = this.username;
113 this.contentElement.appendChild(usernameDiv); 141 this.contentElement.appendChild(usernameDiv);
114 var usernameInput = this.ownerDocument.createElement('input'); 142 var usernameInput = this.ownerDocument.createElement('input');
115 usernameInput.type = 'text'; 143 usernameInput.type = 'text';
116 usernameInput.className = 'inactive-item'; 144 usernameInput.className = 'inactive-item';
117 usernameInput.readOnly = true; 145 usernameInput.readOnly = true;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 onClick_: function(event) { 279 onClick_: function(event) {
252 if (this.passwordField.type == 'password') { 280 if (this.passwordField.type == 'password') {
253 // After the user is authenticated, showPassword() will be called. 281 // After the user is authenticated, showPassword() will be called.
254 PasswordManager.requestShowPassword(this.getOriginalIndex_()); 282 PasswordManager.requestShowPassword(this.getOriginalIndex_());
255 } else { 283 } else {
256 this.hidePassword(); 284 this.hidePassword();
257 } 285 }
258 }, 286 },
259 287
260 /** 288 /**
261 * Get and set the URL for the entry. 289 * Get the URL for the entry.
262 * @type {string} 290 * @type {string}
263 */ 291 */
264 get url() { 292 get url() {
265 return this.dataItem[ORIGIN_FIELD]; 293 return this.dataItem[URL_FIELD];
266 },
267 set url(url) {
268 this.dataItem[ORIGIN_FIELD] = url;
269 }, 294 },
270 295
271 /** 296 /**
272 * Get and set the shown url for the entry. 297 * Get the shown origin for the entry.
273 * @type {string} 298 * @type {string}
274 */ 299 */
275 get shownUrl() { 300 get shownOrigin() {
276 return this.dataItem[SHOWN_URL_FIELD]; 301 return this.dataItem[SHOWN_ORIGIN_FIELD];
277 },
278 set shownUrl(shownUrl) {
279 this.dataItem[SHOWN_URL_FIELD] = shownUrl;
280 }, 302 },
281 303
282 /** 304 /**
283 * Get and set whether the origin is Android URI. 305 * Get whether the origin is Android URI.
284 * @type {boolean} 306 * @type {boolean}
285 */ 307 */
286 get isAndroidUri() { 308 get isAndroidUri() {
287 return this.dataItem[IS_ANDROID_URI_FIELD]; 309 return this.dataItem[IS_ANDROID_URI_FIELD];
288 }, 310 },
289 set isAndroidUri(isAndroidUri) { 311
290 this.dataItem[IS_ANDROID_URI_FIELD] = isAndroidUri; 312 /**
313 * Get whether the origin is clickable.
314 * @type {boolean}
315 */
316 get isClickable() {
317 return this.dataItem[IS_CLICKABLE_FIELD];
291 }, 318 },
292 319
293 /** 320 /**
294 * Get and set whether the origin uses secure scheme. 321 * Get whether the origin uses secure scheme.
295 * @type {boolean} 322 * @type {boolean}
296 */ 323 */
297 get isSecure() { 324 get isSecure() {
298 return this.dataItem[IS_SECURE_FIELD]; 325 return this.dataItem[IS_SECURE_FIELD];
299 }, 326 },
300 set isSecure(isSecure) {
301 this.dataItem[IS_SECURE_FIELD] = isSecure;
302 },
303 327
304 /** 328 /**
305 * Get and set the username for the entry. 329 * Get the username for the entry.
306 * @type {string} 330 * @type {string}
307 */ 331 */
308 get username() { 332 get username() {
309 return this.dataItem[USERNAME_FIELD]; 333 return this.dataItem[USERNAME_FIELD];
310 }, 334 },
311 set username(username) {
312 this.dataItem[USERNAME_FIELD] = username;
313 },
314 335
315 /** 336 /**
316 * Get and set the password for the entry. 337 * Get the password for the entry.
317 * @type {string} 338 * @type {string}
318 */ 339 */
319 get password() { 340 get password() {
320 return this.dataItem[PASSWORD_FIELD]; 341 return this.dataItem[PASSWORD_FIELD];
321 }, 342 },
322 set password(password) {
323 this.dataItem[PASSWORD_FIELD] = password;
324 },
325 343
326 /** 344 /**
327 * Get and set the federation for the entry. 345 * Get the federation for the entry.
328 * @type {string} 346 * @type {string}
329 */ 347 */
330 get federation() { 348 get federation() {
331 return this.dataItem[FEDERATION_FIELD]; 349 return this.dataItem[FEDERATION_FIELD];
332 }, 350 },
333 set federation(federation) {
334 this.dataItem[FEDERATION_FIELD] = federation;
335 },
336 }; 351 };
337 352
338 /** 353 /**
339 * Creates a new PasswordExceptions list item. 354 * Creates a new PasswordExceptions list item.
340 * @param {Object} entry A dictionary of data on new list item. 355 * @param {Object} entry A dictionary of data on new list item.
341 * @constructor 356 * @constructor
342 * @extends {options.DeletableItem} 357 * @extends {options.DeletableItem}
343 */ 358 */
344 function PasswordExceptionsListItem(entry) { 359 function PasswordExceptionsListItem(entry) {
345 var el = cr.doc.createElement('div'); 360 var el = cr.doc.createElement('div');
346 el.dataItem = entry; 361 el.dataItem = entry;
347 el.__proto__ = PasswordExceptionsListItem.prototype; 362 el.__proto__ = PasswordExceptionsListItem.prototype;
348 el.decorate(); 363 el.decorate();
349 364
350 return el; 365 return el;
351 } 366 }
352 367
353 PasswordExceptionsListItem.prototype = { 368 PasswordExceptionsListItem.prototype = {
354 __proto__: DeletableItem.prototype, 369 __proto__: DeletableItem.prototype,
355 370
356 /** 371 /**
357 * Call when an element is decorated as a list item. 372 * Call when an element is decorated as a list item.
358 */ 373 */
359 decorate: function() { 374 decorate: function() {
360 DeletableItem.prototype.decorate.call(this); 375 DeletableItem.prototype.decorate.call(this);
361 376
362 // The URL of the site. 377 // The URL of the site.
363 var urlDiv = this.ownerDocument.createElement('div'); 378 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 }, 379 },
375 380
376 /** @override */ 381 /** @override */
377 selectionChanged: function() { 382 selectionChanged: function() {
378 if (this.selected) { 383 if (this.selected) {
379 this.setFocusable_(true); 384 this.setFocusable_(true);
380 this.urlLink.focus(); 385 this.urlLink.focus();
381 } else { 386 } else {
382 this.setFocusable_(false); 387 this.setFocusable_(false);
383 } 388 }
384 }, 389 },
385 390
386 /** 391 /**
387 * Set the focusability of this row. 392 * Set the focusability of this row.
388 * @param {boolean} focusable 393 * @param {boolean} focusable
389 * @private 394 * @private
390 */ 395 */
391 setFocusable_: function(focusable) { 396 setFocusable_: function(focusable) {
392 var tabIndex = focusable ? 0 : -1; 397 var tabIndex = focusable ? 0 : -1;
393 this.urlLink.tabIndex = tabIndex; 398 this.urlLink.tabIndex = tabIndex;
394 this.closeButtonElement.tabIndex = tabIndex; 399 this.closeButtonElement.tabIndex = tabIndex;
395 }, 400 },
396 401
397 /** 402 /**
398 * Get the url for the entry. 403 * Get the url for the entry.
399 * @type {string} 404 * @type {string}
400 */ 405 */
401 get url() { 406 get url() {
402 return this.dataItem[ORIGIN_FIELD]; 407 return this.dataItem[URL_FIELD];
403 },
404 set url(url) {
405 this.dataItem[ORIGIN_FIELD] = url;
406 }, 408 },
407 409
408 /** 410 /**
409 * Get and set the shown url for the entry. 411 * Get the shown origin for the entry.
410 * @type {string} 412 * @type {string}
411 */ 413 */
412 get shownUrl() { 414 get shownOrigin() {
413 return this.dataItem[SHOWN_URL_FIELD]; 415 return this.dataItem[SHOWN_ORIGIN_FIELD];
414 },
415 set shownUrl(shownUrl) {
416 this.dataItem[SHOWN_URL_FIELD] = shownUrl;
417 }, 416 },
418 417
419 /** 418 /**
420 * Get and set whether the origin is Android URI. 419 * Get whether the origin is Android URI.
421 * @type {boolean} 420 * @type {boolean}
422 */ 421 */
423 get isAndroidUri() { 422 get isAndroidUri() {
424 return this.dataItem[IS_ANDROID_URI_FIELD]; 423 return this.dataItem[IS_ANDROID_URI_FIELD];
425 }, 424 },
426 set isAndroidUri(isAndroidUri) { 425
427 this.dataItem[IS_ANDROID_URI_FIELD] = isAndroidUri; 426 /**
427 * Get whether the origin is clickable.
428 * @type {boolean}
429 */
430 get isClickable() {
431 return this.dataItem[IS_CLICKABLE_FIELD];
428 }, 432 },
429 433
430 /** 434 /**
431 * Get and set whether the origin uses secure scheme. 435 * Get whether the origin uses secure scheme.
432 * @type {boolean} 436 * @type {boolean}
433 */ 437 */
434 get isSecure() { 438 get isSecure() {
435 return this.dataItem[IS_SECURE_FIELD]; 439 return this.dataItem[IS_SECURE_FIELD];
436 }, 440 },
437 set isSecure(isSecure) {
438 this.dataItem[IS_SECURE_FIELD] = isSecure;
439 },
440 }; 441 };
441 442
442 /** 443 /**
443 * Create a new passwords list. 444 * Create a new passwords list.
444 * @constructor 445 * @constructor
445 * @extends {options.DeletableItemList} 446 * @extends {options.DeletableItemList}
446 */ 447 */
447 var PasswordsList = cr.ui.define('list'); 448 var PasswordsList = cr.ui.define('list');
448 449
449 PasswordsList.prototype = { 450 PasswordsList.prototype = {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 get length() { 547 get length() {
547 return this.dataModel.length; 548 return this.dataModel.length;
548 }, 549 },
549 }; 550 };
550 551
551 return { 552 return {
552 PasswordListItem: PasswordListItem, 553 PasswordListItem: PasswordListItem,
553 PasswordExceptionsListItem: PasswordExceptionsListItem, 554 PasswordExceptionsListItem: PasswordExceptionsListItem,
554 PasswordsList: PasswordsList, 555 PasswordsList: PasswordsList,
555 PasswordExceptionsList: PasswordExceptionsList, 556 PasswordExceptionsList: PasswordExceptionsList,
556 ORIGIN_FIELD: ORIGIN_FIELD, 557 URL_FIELD: URL_FIELD,
557 SHOWN_URL_FIELD: SHOWN_URL_FIELD, 558 SHOWN_ORIGIN_FIELD: SHOWN_ORIGIN_FIELD,
559 IS_ANDROID_URI_FIELD: IS_ANDROID_URI_FIELD,
560 IS_CLICKABLE_FIELD: IS_CLICKABLE_FIELD,
558 IS_SECURE_FIELD: IS_SECURE_FIELD, 561 IS_SECURE_FIELD: IS_SECURE_FIELD,
559 USERNAME_FIELD: USERNAME_FIELD, 562 USERNAME_FIELD: USERNAME_FIELD,
560 PASSWORD_FIELD: PASSWORD_FIELD, 563 PASSWORD_FIELD: PASSWORD_FIELD,
561 FEDERATION_FIELD: FEDERATION_FIELD, 564 FEDERATION_FIELD: FEDERATION_FIELD,
562 ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD 565 ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD
563 }; 566 };
564 }); 567 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698