Bug 854796: Anchor, area elements without href shouldn't have link role, r=Jamie,devtools-reviewers

Per the HTML-AAM spec, a and area elements without href attributes should have
generic roles. This revision implements this preference by creating hypertext
accessibles when said elements lack href attributes (or click listeners). A
byproduct of this change is recognizing that a elements have no intrinsic role
mapping; they could be generics or links. This revision handles situations
where href or click listeners might appear or dissapear, and recreates the
accessibles when necessary. Since image map areas are handled by their
containing image maps, this revision specializes HTMLAreaAccessible::NativeRole
to account for the discrepancy that we can't account for in the markup map.
This revision also changes the relevant WPT test expectations, updates existing
tests that this change affects, and adds tests to verify that changing href
and click listeners dynamically changes the role appropriately.

Differential Revision: https://phabricator.services.mozilla.com/D183550
This commit is contained in:
Nathan LaPre
2023-07-24 19:31:29 +00:00
parent 3dbceec0ba
commit 1055f41a81
22 changed files with 344 additions and 83 deletions

View File

@@ -442,17 +442,33 @@ nsAccessibilityService::ListenersChanged(nsIArray* aEventChanges) {
content == document->DocumentNode()->GetRootElement())) {
acc = document;
}
if (!acc && content->IsElement() &&
content->AsElement()->IsHTMLElement(nsGkAtoms::area)) {
// For area accessibles, we have to recreate the entire image map,
// since the image map accessible manages the tree itself. The click
// listener change may require us to update the role for the
// accessible associated with the area element.
LocalAccessible* areaAcc =
document->GetAccessibleEvenIfNotInMap(content);
if (areaAcc && areaAcc->LocalParent()) {
document->RecreateAccessible(areaAcc->LocalParent()->GetContent());
}
}
if (!acc && nsCoreUtils::HasClickListener(content)) {
// Create an accessible for a inaccessible element having click event
// handler.
document->ContentInserted(content, content->GetNextSibling());
} else if (acc) {
if (acc->IsHTMLLink() && !acc->AsHTMLLink()->IsLinked()) {
// Notify of a LINKED state change if an HTML link gets a click
// listener but does not have an href attribute.
RefPtr<AccEvent> linkedChangeEvent =
new AccStateChangeEvent(acc, states::LINKED);
document->FireDelayedEvent(linkedChangeEvent);
if ((acc->IsHTMLLink() && !acc->AsHTMLLink()->IsLinked()) ||
(content->IsElement() &&
content->AsElement()->IsHTMLElement(nsGkAtoms::a) &&
!acc->IsHTMLLink())) {
// An HTML link without an href attribute should have a generic
// role, unless it has a click listener. Since we might have gained
// or lost a click listener here, recreate the accessible so that we
// can create the correct type of accessible. If it was a link, it
// may no longer be one. If it wasn't, it may become one.
document->RecreateAccessible(content);
}
// A click listener change might mean losing or gaining an action.