Bug 1583425 - Update the active descendant when rendering to make sure that it is a visible list-item. r?sfoster
authorJared Wein <jwein@mozilla.com>
Tue, 01 Oct 2019 16:44:52 -0400
changeset 552246 304bc94e13042c3f7b638e7bd5da147e0ae31864
parent 552245 570504a161f475d6d9c5c9249c42a590304f7db2
child 552247 5ff97d3d6f8b9352f8431dac497e06a0e445debf
push id12106
push userjwein@mozilla.com
push dateFri, 04 Oct 2019 17:46:23 +0000
treeherdermozilla-beta@90d8a6faebc4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfoster
bugs1583425
milestone70.0
Bug 1583425 - Update the active descendant when rendering to make sure that it is a visible list-item. r?sfoster Differential Revision: https://phabricator.services.mozilla.com/D47827
browser/components/aboutlogins/content/components/login-list.css
browser/components/aboutlogins/content/components/login-list.js
browser/components/aboutlogins/tests/browser/browser_openFiltered.js
--- a/browser/components/aboutlogins/content/components/login-list.css
+++ b/browser/components/aboutlogins/content/components/login-list.css
@@ -52,18 +52,17 @@
 }
 
 :host(.no-logins) .empty-search-message,
 :host(:not(.empty-search)) .empty-search-message,
 :host(.empty-search:not(.create-login-selected)) ol,
 :host(.no-logins:not(.create-login-selected)) ol,
 :host(:not(.no-logins)) .intro,
 :host(.create-login-selected) .intro,
-:host(.create-login-selected) .empty-search-message,
-:host(:not(.create-login-selected)) #new-login-list-item {
+:host(.create-login-selected) .empty-search-message {
   display: none;
 }
 
 .empty-search-message,
 .intro {
   text-align: center;
   padding: 1em;
   max-width: 50ch; /* This should be kept in sync with login-list-item username and title max-width */
--- a/browser/components/aboutlogins/content/components/login-list.js
+++ b/browser/components/aboutlogins/content/components/login-list.js
@@ -113,16 +113,28 @@ export default class LoginList extends H
     for (let i = this._loginGuidsSortedOrder.length - 1; i >= 0; i--) {
       let guid = this._loginGuidsSortedOrder[i];
       let { listItem } = this._logins[guid];
       this._list.insertBefore(
         listItem,
         this._blankLoginListItem.nextElementSibling
       );
     }
+
+    let activeDescendantId = this._list.getAttribute("aria-activedescendant");
+    let activeDescendant =
+      activeDescendantId && this.shadowRoot.getElementById(activeDescendantId);
+    if (!activeDescendant || activeDescendant.hidden) {
+      let visibleListItem = this._list.querySelector(
+        ".login-list-item:not([hidden])"
+      );
+      if (visibleListItem) {
+        this._list.setAttribute("aria-activedescendant", visibleListItem.id);
+      }
+    }
   }
 
   handleEvent(event) {
     switch (event.type) {
       case "click": {
         if (event.originalTarget == this._createLoginButton) {
           window.dispatchEvent(
             new CustomEvent("AboutLoginsShowBlankLogin", {
@@ -576,16 +588,17 @@ export default class LoginList extends H
 
   _setListItemAsSelected(listItem) {
     let oldSelectedItem = this._list.querySelector(".selected");
     if (oldSelectedItem) {
       oldSelectedItem.classList.remove("selected");
       oldSelectedItem.removeAttribute("aria-selected");
     }
     this.classList.toggle("create-login-selected", !listItem.dataset.guid);
+    this._blankLoginListItem.hidden = !!listItem.dataset.guid;
     this._createLoginButton.disabled = !listItem.dataset.guid;
     listItem.classList.add("selected");
     listItem.setAttribute("aria-selected", "true");
     this._list.setAttribute("aria-activedescendant", listItem.id);
     this._selectedGuid = listItem.dataset.guid;
 
     // Scroll item into view if it isn't visible
     listItem.scrollIntoView({ block: "nearest" });
--- a/browser/components/aboutlogins/tests/browser/browser_openFiltered.js
+++ b/browser/components/aboutlogins/tests/browser/browser_openFiltered.js
@@ -76,17 +76,17 @@ add_task(async function test_query_param
     );
     is(
       loginFilter.shadowRoot.activeElement,
       loginFilter.shadowRoot.querySelector(".filter"),
       "the actual input inside of login-filter should be focused"
     );
 
     let hiddenLoginListItems = loginList.shadowRoot.querySelectorAll(
-      ".login-list-item[hidden]"
+      ".login-list-item:not(#new-login-list-item)[hidden]"
     );
     let visibleLoginListItems = loginList.shadowRoot.querySelectorAll(
       ".login-list-item:not(#new-login-list-item):not([hidden])"
     );
     is(visibleLoginListItems.length, 1, "The one login should be visible");
     is(
       visibleLoginListItems[0].dataset.guid,
       logins[0].guid,