Bug 1646267: In Dev Tools autocompletes, Only rebuild the list a11y clone when the main list changes. r=nchevobbe

Previously, the list clone was completely replaced every time aria-activedescendant was set.
This caused screen readers to extraneously report this as a new list every time the user cursored to a different item, even if the items hadn't changed.

Differential Revision: https://phabricator.services.mozilla.com/D79941
This commit is contained in:
James Teh 2020-06-23 01:57:52 +00:00
Родитель 0a77ea61d7
Коммит 316e5c9eca
2 изменённых файлов: 28 добавлений и 15 удалений

Просмотреть файл

@ -343,8 +343,11 @@ AutocompletePopup.prototype = {
maxLabelLength = Math.max(label.length, maxLabelLength);
});
const fragmentClone = fragment.cloneNode(true);
this.list.style.width = maxLabelLength + 3 + "ch";
this.list.appendChild(fragment);
// Update the clone content to match the current list content.
this._listClone.appendChild(fragmentClone);
this.selectItemAtIndex(selectedIndex, options);
},
@ -376,6 +379,9 @@ AutocompletePopup.prototype = {
if (this._list) {
this._list.innerHTML = "";
}
if (this._listClone) {
this._listClone.innerHTML = "";
}
this.items = [];
this.elements = new WeakMap();
@ -424,14 +430,6 @@ AutocompletePopup.prototype = {
anchorDoc.documentElement.appendChild(this._listClone);
}
// Update the clone content to match the current list content.
const clone = this.list.cloneNode(true);
clone.className = "devtools-autocomplete-list-aria-clone";
this._listClone.replaceWith(clone);
// We also need to update the reference.
this._listClone = clone;
this._activeElement.setAttribute("aria-activedescendant", id);
},

Просмотреть файл

@ -45,37 +45,40 @@ add_task(async function() {
);
is(popup.selectedIndex, 0, "Index of the first item from top is selected.");
is(popup.selectedItem, items[0], "First item from top is selected");
checkActiveDescendant(popup, input);
// Make sure the list containing the active descendant doesn't get rebuilt
// when the selected item changes.
const listClone = getListFromActiveDescendant(popup, input);
checkActiveDescendant(popup, input, listClone);
popup.selectItemAtIndex(1);
is(popup.selectedIndex, 1, "index 1 is selected");
is(popup.selectedItem, items[1], "item1 is selected");
checkActiveDescendant(popup, input);
checkActiveDescendant(popup, input, listClone);
popup.selectedItem = items[2];
is(popup.selectedIndex, 2, "index 2 is selected");
is(popup.selectedItem, items[2], "item2 is selected");
checkActiveDescendant(popup, input);
checkActiveDescendant(popup, input, listClone);
is(popup.selectPreviousItem(), items[1], "selectPreviousItem() works");
is(popup.selectedIndex, 1, "index 1 is selected");
is(popup.selectedItem, items[1], "item1 is selected");
checkActiveDescendant(popup, input);
checkActiveDescendant(popup, input, listClone);
is(popup.selectNextItem(), items[2], "selectNextItem() works");
is(popup.selectedIndex, 2, "index 2 is selected");
is(popup.selectedItem, items[2], "item2 is selected");
checkActiveDescendant(popup, input);
checkActiveDescendant(popup, input, listClone);
ok(popup.selectNextItem(), "selectNextItem() works");
is(popup.selectedIndex, 0, "index 0 is selected");
is(popup.selectedItem, items[0], "item0 is selected");
checkActiveDescendant(popup, input);
checkActiveDescendant(popup, input, listClone);
popup.clearItems();
is(popup.itemCount, 0, "items cleared");
@ -90,7 +93,14 @@ function stripNS(text) {
return text.replace(RegExp(' xmlns="http://www.w3.org/1999/xhtml"', "g"), "");
}
function checkActiveDescendant(popup, input) {
function getListFromActiveDescendant(popup, input) {
const activeElement = input.ownerDocument.activeElement;
const descendantId = activeElement.getAttribute("aria-activedescendant");
const cloneItem = input.ownerDocument.querySelector("#" + descendantId);
return cloneItem.parentNode;
}
function checkActiveDescendant(popup, input, list) {
const activeElement = input.ownerDocument.activeElement;
const descendantId = activeElement.getAttribute("aria-activedescendant");
const popupItem = popup._tooltip.panel.querySelector("#" + descendantId);
@ -98,6 +108,11 @@ function checkActiveDescendant(popup, input) {
ok(popupItem, "Active descendant is found in the popup list");
ok(cloneItem, "Active descendant is found in the list clone");
is(
cloneItem.parentNode,
list,
"Active descendant is a child of the expected list"
);
is(
stripNS(popupItem.outerHTML),
cloneItem.outerHTML,