зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
0a77ea61d7
Коммит
316e5c9eca
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче