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

Unified 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: Changes with StringPiece 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options/password_manager_list.js
diff --git a/chrome/browser/resources/options/password_manager_list.js b/chrome/browser/resources/options/password_manager_list.js
index f8ed9e8a5fdc5423ac10318d6bacaf1bb2450d75..c4af28d4ba7eec8d0731da282629d46338877f75 100644
--- a/chrome/browser/resources/options/password_manager_list.js
+++ b/chrome/browser/resources/options/password_manager_list.js
@@ -8,11 +8,15 @@ cr.define('options.passwordManager', function() {
/** @const */ var DeletableItem = options.DeletableItem;
/** @const */ var List = cr.ui.List;
- /** @const */ var URL_DATA_INDEX = 0;
- /** @const */ var USERNAME_DATA_INDEX = 1;
- /** @const */ var PASSWORD_DATA_INDEX = 2;
- /** @const */ var FEDERATION_DATA_INDEX = 3;
- /** @const */ var ORIGINAL_DATA_INDEX = 4;
+ // The following constants should be synchronized with the constants in
+ // chrome/browser/ui/webui/options/password_manager_handler.cc.
+ /** @const */ var ORIGIN_FIELD = 'origin';
+ /** @const */ var SHOWN_URL_FIELD = 'shownUrl';
+ /** @const */ var IS_SECURE_FIELD = 'isSecure';
+ /** @const */ var USERNAME_FIELD = 'username';
+ /** @const */ var PASSWORD_FIELD = 'password';
+ /** @const */ var FEDERATION_FIELD = 'federation';
+ /** @const */ var ORIGINAL_INDEX_FIELD = 'index';
/**
* Creates a new passwords list item.
@@ -37,6 +41,26 @@ cr.define('options.passwordManager', function() {
return el;
}
+ /**
+ * Returns title for password's origin (removes the scheme if the url is
+ * insecure and removes trailing punctuation symbols).
+ * @param {string} url The url.
+ * @param {boolean} isSecure True if the url is secure.
+ * @return {string} The title for password's origin.
+ */
+ function getTitleForPasswordOrigin(url, isSecure) {
+ if (!isSecure) {
+ var ind = url.indexOf('://');
+ if (ind >= 0) {
+ url = url.substring(ind + 3);
+ }
+ }
+ // Since the direction is switched to RTL, punctuation symbols appear on the
+ // left side, that is wrong. So, just remove trailing punctuation symbols.
+ url = url.replace(/[^A-Za-z0-9]+$/, '');
+ return url;
+ }
+
PasswordListItem.prototype = {
__proto__: DeletableItem.prototype,
@@ -45,28 +69,30 @@ cr.define('options.passwordManager', function() {
DeletableItem.prototype.decorate.call(this);
// The URL of the site.
- var urlLabel = this.ownerDocument.createElement('div');
- urlLabel.classList.add('favicon-cell');
- urlLabel.classList.add('weakrtl');
- urlLabel.classList.add('url');
- urlLabel.setAttribute('title', this.url);
- urlLabel.textContent = this.url;
-
- // The favicon URL is prefixed with "origin/", which essentially removes
- // the URL path past the top-level domain and ensures that a scheme (e.g.,
- // http) is being used. This ensures that the favicon returned is the
- // default favicon for the domain and that the URL has a scheme if none
- // is present in the password manager.
- urlLabel.style.backgroundImage = getFaviconImageSet(
+ var urlDiv = this.ownerDocument.createElement('div');
+ urlDiv.className = 'favicon-cell left-elided-url url';
+ urlDiv.setAttribute(
+ 'title', getTitleForPasswordOrigin(this.url, this.isUrlSecure));
+ var urlLink = this.ownerDocument.createElement('a');
+ urlLink.href = this.url;
+ urlLink.textContent = this.shownUrl.split('').reverse().join('');
+ urlDiv.appendChild(urlLink);
+ urlDiv.style.backgroundImage = getFaviconImageSet(
'origin/' + this.url, 16);
- this.contentElement.appendChild(urlLabel);
+ this.contentElement.appendChild(urlDiv);
// The stored username.
- var usernameLabel = this.ownerDocument.createElement('div');
- usernameLabel.className = 'name';
- usernameLabel.textContent = this.username;
- usernameLabel.title = this.username;
- this.contentElement.appendChild(usernameLabel);
+ var usernameDiv = this.ownerDocument.createElement('div');
+ usernameDiv.className = 'name';
+ usernameDiv.title = this.username;
+ this.contentElement.appendChild(usernameDiv);
+ var usernameInput = this.ownerDocument.createElement('input');
+ usernameInput.type = 'text';
+ usernameInput.className = 'inactive-item';
+ usernameInput.readOnly = true;
+ usernameInput.value = this.username;
+ usernameDiv.appendChild(usernameInput);
+ this.usernameField = usernameInput;
if (this.federation) {
// The federation.
@@ -82,7 +108,7 @@ cr.define('options.passwordManager', function() {
// The password input field.
var passwordInput = this.ownerDocument.createElement('input');
passwordInput.type = 'password';
- passwordInput.className = 'inactive-password';
+ passwordInput.className = 'inactive-item';
passwordInput.readOnly = true;
passwordInput.value = this.showPasswords_ ? this.password : '********';
passwordInputDiv.appendChild(passwordInput);
@@ -114,24 +140,26 @@ cr.define('options.passwordManager', function() {
}
this.contentElement.appendChild(passwordInputDiv);
}
-
},
/** @override */
selectionChanged: function() {
- var input = this.passwordField;
+ var usernameInput = this.usernameField;
+ var passwordInput = this.passwordField;
var button = this.passwordShowButton;
// The button doesn't exist when passwords can't be shown.
if (!button)
return;
if (this.selected) {
- input.classList.remove('inactive-password');
+ usernameInput.classList.remove('inactive-item');
+ passwordInput.classList.remove('inactive-item');
this.setFocusable_(true);
button.hidden = false;
- input.focus();
+ passwordInput.focus();
} else {
- input.classList.add('inactive-password');
+ usernameInput.classList.add('inactive-item');
+ passwordInput.classList.add('inactive-item');
this.setFocusable_(false);
button.hidden = true;
}
@@ -176,7 +204,7 @@ cr.define('options.passwordManager', function() {
* @private
*/
getOriginalIndex_: function() {
- var index = this.dataItem[ORIGINAL_DATA_INDEX];
+ var index = this.dataItem[ORIGINAL_INDEX_FIELD];
return index ? index : this.dataModel.indexOf(this.dataItem);
},
@@ -199,10 +227,32 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get url() {
- return this.dataItem[URL_DATA_INDEX];
+ return this.dataItem[ORIGIN_FIELD];
},
set url(url) {
- this.dataItem[URL_DATA_INDEX] = url;
+ this.dataItem[ORIGIN_FIELD] = url;
+ },
+
+ /**
+ * Get and set the shown url for the entry.
+ * @type {string}
+ */
+ get shownUrl() {
+ return this.dataItem[SHOWN_URL_FIELD];
+ },
+ set shownUrl(shownUrl) {
+ this.dataItem[SHOWN_URL_FIELD] = shownUrl;
+ },
+
+ /**
+ * Get and set whether the origin uses secure scheme.
+ * @type {boolean}
+ */
+ get isUrlSecure() {
+ return this.dataItem[IS_SECURE_FIELD];
+ },
+ set isUrlSecure(isUrlSecure) {
+ this.dataItem[IS_SECURE_FIELD] = isUrlSecure;
},
/**
@@ -210,10 +260,10 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get username() {
- return this.dataItem[USERNAME_DATA_INDEX];
+ return this.dataItem[USERNAME_FIELD];
},
set username(username) {
- this.dataItem[USERNAME_DATA_INDEX] = username;
+ this.dataItem[USERNAME_FIELD] = username;
},
/**
@@ -221,10 +271,10 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get password() {
- return this.dataItem[PASSWORD_DATA_INDEX];
+ return this.dataItem[PASSWORD_FIELD];
},
set password(password) {
- this.dataItem[PASSWORD_DATA_INDEX] = password;
+ this.dataItem[PASSWORD_FIELD] = password;
},
/**
@@ -232,10 +282,10 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get federation() {
- return this.dataItem[FEDERATION_DATA_INDEX];
+ return this.dataItem[FEDERATION_FIELD];
},
set federation(federation) {
- this.dataItem[FEDERATION_DATA_INDEX] = federation;
+ this.dataItem[FEDERATION_FIELD] = federation;
},
};
@@ -264,20 +314,19 @@ cr.define('options.passwordManager', function() {
DeletableItem.prototype.decorate.call(this);
// The URL of the site.
- var urlLabel = this.ownerDocument.createElement('div');
- urlLabel.className = 'url';
- urlLabel.classList.add('favicon-cell');
- urlLabel.classList.add('weakrtl');
- urlLabel.textContent = this.url;
-
- // The favicon URL is prefixed with "origin/", which essentially removes
- // the URL path past the top-level domain and ensures that a scheme (e.g.,
- // http) is being used. This ensures that the favicon returned is the
- // default favicon for the domain and that the URL has a scheme if none
- // is present in the password manager.
- urlLabel.style.backgroundImage = getFaviconImageSet(
+ var urlDiv = this.ownerDocument.createElement('div');
+ urlDiv.className = 'url';
+ urlDiv.classList.add('favicon-cell');
+ urlDiv.classList.add('left-elided-url');
+ urlDiv.setAttribute(
+ 'title', getTitleForPasswordOrigin(this.url, this.isUrlSecure));
+ var urlLink = this.ownerDocument.createElement('a');
+ urlLink.href = this.url;
+ urlLink.textContent = this.shownUrl.split('').reverse().join('');
+ urlDiv.appendChild(urlLink);
+ urlDiv.style.backgroundImage = getFaviconImageSet(
'origin/' + this.url, 16);
- this.contentElement.appendChild(urlLabel);
+ this.contentElement.appendChild(urlDiv);
},
/**
@@ -285,10 +334,32 @@ cr.define('options.passwordManager', function() {
* @type {string}
*/
get url() {
- return this.dataItem;
+ return this.dataItem[ORIGIN_FIELD];
},
set url(url) {
- this.dataItem = url;
+ this.dataItem[ORIGIN_FIELD] = url;
+ },
+
+ /**
+ * Get and set the shown url for the entry.
+ * @type {string}
+ */
+ get shownUrl() {
+ return this.dataItem[SHOWN_URL_FIELD];
+ },
+ set shownUrl(shownUrl) {
+ this.dataItem[SHOWN_URL_FIELD] = shownUrl;
+ },
+
+ /**
+ * Get and set whether the origin uses secure scheme.
+ * @type {boolean}
+ */
+ get isUrlSecure() {
+ return this.dataItem[IS_SECURE_FIELD];
+ },
+ set isUrlSecure(isUrlSecure) {
+ this.dataItem[IS_SECURE_FIELD] = isUrlSecure;
},
};
@@ -344,9 +415,9 @@ cr.define('options.passwordManager', function() {
/** @override */
deleteItemAtIndex: function(index) {
var item = this.dataModel.item(index);
- if (item && item[ORIGINAL_DATA_INDEX] != undefined) {
+ if (item && item[ORIGINAL_INDEX_FIELD] != undefined) {
// The fifth element, if present, is the original index to delete.
- index = item[ORIGINAL_DATA_INDEX];
+ index = item[ORIGINAL_INDEX_FIELD];
}
PasswordManager.removeSavedPassword(index);
},
@@ -406,5 +477,12 @@ cr.define('options.passwordManager', function() {
PasswordExceptionsListItem: PasswordExceptionsListItem,
PasswordsList: PasswordsList,
PasswordExceptionsList: PasswordExceptionsList,
+ ORIGIN_FIELD: ORIGIN_FIELD,
+ SHOWN_URL_FIELD: SHOWN_URL_FIELD,
+ IS_SECURE_FIELD: IS_SECURE_FIELD,
+ USERNAME_FIELD: USERNAME_FIELD,
+ PASSWORD_FIELD: PASSWORD_FIELD,
+ FEDERATION_FIELD: FEDERATION_FIELD,
+ ORIGINAL_INDEX_FIELD: ORIGINAL_INDEX_FIELD
};
});

Powered by Google App Engine
This is Rietveld 408576698