From 41e9bb84a6f0b56641634bd3f3ec661fb5bf3111 Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Fri, 14 Jun 2019 13:53:00 +0000 Subject: [PATCH] Bug 1553209 - Show '(no username)' as the username for logins that lack a username. r=MattN,fluent-reviewers,flod Differential Revision: https://phabricator.services.mozilla.com/D34467 --HG-- extra : moz-landing-system : lando --- .../aboutlogins/content/aboutLogins.ftl | 1 + .../aboutlogins/content/aboutLogins.html | 1 + .../content/components/login-list-item.js | 2 +- .../content/components/login-list.js | 18 +++++++++---- .../tests/chrome/test_login_list.html | 27 +++++++++++++++++-- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/browser/components/aboutlogins/content/aboutLogins.ftl b/browser/components/aboutlogins/content/aboutLogins.ftl index fe17e85c1ff4..3b4c1b8323aa 100644 --- a/browser/components/aboutlogins/content/aboutLogins.ftl +++ b/browser/components/aboutlogins/content/aboutLogins.ftl @@ -25,6 +25,7 @@ login-list = } .last-changed-option = Last Changed .last-used-option = Last Used + .missing-username = (no username) .name-option = Name .new-login-subtitle = Enter your login credentials .new-login-title = New Login diff --git a/browser/components/aboutlogins/content/aboutLogins.html b/browser/components/aboutlogins/content/aboutLogins.html index 5996b2a52665..5f5b2e5174c3 100644 --- a/browser/components/aboutlogins/content/aboutLogins.html +++ b/browser/components/aboutlogins/content/aboutLogins.html @@ -34,6 +34,7 @@ data-l10n-attrs="count, last-changed-option, last-used-option, + missing-username, name-option, new-login-subtitle, new-login-title, diff --git a/browser/components/aboutlogins/content/components/login-list-item.js b/browser/components/aboutlogins/content/components/login-list-item.js index f3036b3f4de9..aae1de438c16 100644 --- a/browser/components/aboutlogins/content/components/login-list-item.js +++ b/browser/components/aboutlogins/content/components/login-list-item.js @@ -37,7 +37,7 @@ export default class LoginListItem extends HTMLElement { this.setAttribute("guid", this._login.guid); origin.textContent = this._login.origin; - username.textContent = this._login.username; + username.textContent = this._login.username.trim() || this.getAttribute("missing-username"); } handleEvent(event) { diff --git a/browser/components/aboutlogins/content/components/login-list.js b/browser/components/aboutlogins/content/components/login-list.js index 7ed1431a0d0e..bc6e8b2d82fc 100644 --- a/browser/components/aboutlogins/content/components/login-list.js +++ b/browser/components/aboutlogins/content/components/login-list.js @@ -55,6 +55,7 @@ export default class LoginList extends ReflectedFluentElement { for (let login of this._logins) { let listItem = new LoginListItem(login); + listItem.setAttribute("missing-username", this.getAttribute("missing-username")); if (login.guid == this._selectedGuid) { listItem.classList.add("selected"); } @@ -122,6 +123,7 @@ export default class LoginList extends ReflectedFluentElement { return ["count", "last-used-option", "last-changed-option", + "missing-username", "name-option", "new-login-subtitle", "new-login-title", @@ -133,12 +135,18 @@ export default class LoginList extends ReflectedFluentElement { } handleSpecialCaseFluentString(attrName) { - if (attrName != "new-login-subtitle" && - attrName != "new-login-title") { - return false; + switch (attrName) { + case "missing-username": { + break; + } + case "new-login-subtitle": + case "new-login-title": { + this._blankLoginListItem.setAttribute(attrName, this.getAttribute(attrName)); + break; + } + default: + return false; } - - this._blankLoginListItem.setAttribute(attrName, this.getAttribute(attrName)); return true; } diff --git a/browser/components/aboutlogins/tests/chrome/test_login_list.html b/browser/components/aboutlogins/tests/chrome/test_login_list.html index a8dccaf202ba..bcdd5da928ef 100644 --- a/browser/components/aboutlogins/tests/chrome/test_login_list.html +++ b/browser/components/aboutlogins/tests/chrome/test_login_list.html @@ -27,10 +27,10 @@ Test the login-list component let gLoginList; const TEST_LOGIN_1 = { guid: "123456789", - origin: "https://abc-example.com", + origin: "https://abc.example.com", username: "user1", password: "pass1", - title: "abc-example.com", + title: "abc.example.com", // new Date("December 13, 2018").getTime() timeLastUsed: 1544677200000, timePasswordChanged: 1544677200000, @@ -45,6 +45,16 @@ const TEST_LOGIN_2 = { timeLastUsed: 1559361600000, timePasswordChanged: 1559361600000, }; +const TEST_LOGIN_3 = { + guid: "1111122222", + origin: "https://def.example.com", + username: "", + password: "pass3", + title: "def.example.com", + // new Date("June 1, 2019").getTime() + timeLastUsed: 1559361600000, + timePasswordChanged: 1559361600000, +}; add_task(async function setup() { stubFluentL10n({ @@ -64,6 +74,19 @@ add_task(async function test_empty_list() { is(gLoginList.textContent, "", "Initially empty"); }); +add_task(async function test_empty_login_username_in_list() { + gLoginList.setLogins([TEST_LOGIN_3]); + let loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item"); + is(loginListItems.length, 2, "A blank login and the one stored login should be displayed"); + ok(!loginListItems[0].hasAttribute("guid"), "first login-list-item should be the 'new' item"); + is(loginListItems[1].getAttribute("guid"), TEST_LOGIN_3.guid, "login-list-item should have correct guid attribute"); + + loginListItems[1].setAttribute("missing-username", "(no username)"); + loginListItems[1].render(); + let loginUsername = loginListItems[1].shadowRoot.querySelector(".username"); + is(loginUsername.textContent, "(no username)", "login should show missing username text"); +}); + add_task(async function test_populated_list() { gLoginList.setLogins([TEST_LOGIN_1, TEST_LOGIN_2]); let loginListItems = gLoginList.shadowRoot.querySelectorAll("login-list-item");