vpat 7,14: popups count and cursor fixes
- vpat_7: when a popup is showing, mark menuseparators with role="presentation" to clear whatever semantics a separator has. It prevents the screen readers from counting it as an interactable element while announcing the index of a menuitem within the popup. It also makes the screen readers count items across all sections, instead of stopping at the first separator. - - vpat_14: when menupopup is hiding, delete it and immediately re-insert back into the DOM. It forces voiceover to move cursor back to the focused element. Otherwise, it is not aware that the popup went away, the cursor gets stuck inside of the invisible menu, no elements will be announced until the screen readers is reloaded.
This commit is contained in:
parent
192ea54de0
commit
ff6d1886b7
1 changed files with 31 additions and 0 deletions
|
@ -114,6 +114,15 @@ Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemPaneSe
|
|||
);
|
||||
this.toggleAttribute("needsgutter", haveCheckableChild);
|
||||
|
||||
// Clear whatever aria semantics the separator has so it is not counted when
|
||||
// voiceover lists how many menuitems a menu has.
|
||||
let clearSeparatorAriaSemantics = () => {
|
||||
for (let separator of [...this.querySelectorAll("menuseparator")]) {
|
||||
separator.setAttribute("role", "presentation");
|
||||
}
|
||||
};
|
||||
clearSeparatorAriaSemantics();
|
||||
|
||||
/**
|
||||
* Add fade animation to the popup
|
||||
* animate="false" will disable the animation
|
||||
|
@ -164,6 +173,28 @@ Services.scriptloader.loadSubScript('chrome://zotero/content/elements/itemPaneSe
|
|||
}, 200);
|
||||
});
|
||||
|
||||
this.addEventListener("popupshowing", clearSeparatorAriaSemantics);
|
||||
|
||||
// If a menu closes with voiceover cursor in it, the cursor gets stuck in no-longer-visible
|
||||
// menu and voiceover will be quiet until it is restarted. As a workaround, remove the menu
|
||||
// from DOM to force voiceover to move its cursor and insert it back after a small delay;
|
||||
this.addEventListener("popuphidden", (e) => {
|
||||
if (this !== e.target || this.parentNode?.closest("menupopup")) {
|
||||
return;
|
||||
}
|
||||
let parent = this.parentNode;
|
||||
let sibling = this.nextSibling;
|
||||
this.remove();
|
||||
setTimeout(() => {
|
||||
if (sibling) {
|
||||
parent.insertBefore(this, sibling);
|
||||
}
|
||||
else {
|
||||
parent.appendChild(this);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// This event is triggered after clicking the menu and before popuphiding
|
||||
// where we control whether the fade out animation should run
|
||||
this.addEventListener("command", () => {
|
||||
|
|
Loading…
Reference in a new issue