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
--- 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,