Chromium Code Reviews| 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'; |
|
Evan Stade
2015/10/26 18:41:13
I'm not entirely convinced this is useful (as oppo
kolos1
2015/10/27 08:24:36
Let me repeat my previous comment.
It collects a
Evan Stade
2015/10/27 16:51:36
well there probably is a need to check all code of
|
| + /** @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 |
| }; |
| }); |