mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 09:12:13 -05:00
LibWeb: Allow accessible-name computation to skip role-attribute lookup
Per https://w3c.github.io/aria/#document-handling_author-errors_roles, determining whether to ignore certain specified landmark roles requires first determining whether the element for which the role is specified has an accessible name. But if we then try to retrieve a role for such elements, we end up calling right back into the accessible-name computation code — which would cause the calls to loop infinitely. So to avoid that — and to have handling for any other future cases the spec may introduce of such recursive calls that will loop indefinitely — this change introduces a parameter that callers can pass to cause role-attribute lookup to be skipped during accessible-name computation.
This commit is contained in:
parent
9f01eebff3
commit
173368bd5e
Notes:
github-actions[bot]
2025-01-09 14:10:02 +00:00
Author: https://github.com/sideshowbarker Commit: https://github.com/LadybirdBrowser/ladybird/commit/173368bd5ea Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2972 Reviewed-by: https://github.com/AtkinsSJ ✅
2 changed files with 20 additions and 7 deletions
|
@ -2347,7 +2347,7 @@ void Node::build_accessibility_tree(AccessibilityTreeNode& parent)
|
|||
}
|
||||
|
||||
// https://www.w3.org/TR/accname-1.2/#mapping_additional_nd_te
|
||||
ErrorOr<String> Node::name_or_description(NameOrDescription target, Document const& document, HashTable<UniqueNodeID>& visited_nodes, IsDescendant is_descendant) const
|
||||
ErrorOr<String> Node::name_or_description(NameOrDescription target, Document const& document, HashTable<UniqueNodeID>& visited_nodes, IsDescendant is_descendant, ShouldComputeRole should_compute_role) const
|
||||
{
|
||||
// The text alternative for a given element is computed as follows:
|
||||
// 1. Set the root node to the given element, the current node to the root node, and the total accumulated text to the
|
||||
|
@ -2359,7 +2359,15 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
|
||||
if (is_element()) {
|
||||
auto const* element = static_cast<DOM::Element const*>(this);
|
||||
auto role = element->role_from_role_attribute_value();
|
||||
Optional<ARIA::Role> role = OptionalNone {};
|
||||
// Per https://w3c.github.io/aria/#document-handling_author-errors_roles, determining whether to ignore certain
|
||||
// specified landmark roles requires first determining, in the ARIAMixin code, whether the element for which the
|
||||
// role is specified has an accessible name — that is, calling into this name_or_description code. But if we
|
||||
// then try to retrieve a role for such elements here, that’d then end up calling right back into this
|
||||
// name_or_description code — which would cause the calls to loop infinitely. So to avoid that, the caller
|
||||
// in the ARIAMixin code can pass the shouldComputeRole parameter to indicate we must skip the role lookup.
|
||||
if (should_compute_role == ShouldComputeRole::Yes)
|
||||
role = element->role_from_role_attribute_value();
|
||||
// Per https://w3c.github.io/html-aam/#el-aside and https://w3c.github.io/html-aam/#el-section, computing a
|
||||
// default role for an aside element or section element requires first computing its accessible name — that is,
|
||||
// calling into this name_or_description code. But if we then try to determine a default role for the aside
|
||||
|
@ -2682,7 +2690,7 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
current_node = child_node;
|
||||
|
||||
// b. Compute the text alternative of the current node beginning with step 2. Set the result to that text alternative.
|
||||
auto result = MUST(current_node->name_or_description(target, document, visited_nodes, IsDescendant::Yes));
|
||||
auto result = MUST(current_node->name_or_description(target, document, visited_nodes, IsDescendant::Yes, should_compute_role));
|
||||
|
||||
// J. Append a space character and the result of each step above to the total accumulated text.
|
||||
// AD-HOC: Doing the space-adding here is in a different order from what the spec states.
|
||||
|
@ -2752,11 +2760,11 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
}
|
||||
|
||||
// https://www.w3.org/TR/accname-1.2/#mapping_additional_nd_name
|
||||
ErrorOr<String> Node::accessible_name(Document const& document) const
|
||||
ErrorOr<String> Node::accessible_name(Document const& document, ShouldComputeRole should_compute_role) const
|
||||
{
|
||||
HashTable<UniqueNodeID> visited_nodes;
|
||||
// User agents MUST compute an accessible name using the rules outlined below in the section titled Accessible Name and Description Computation.
|
||||
return name_or_description(NameOrDescription::Name, document, visited_nodes);
|
||||
return name_or_description(NameOrDescription::Name, document, visited_nodes, IsDescendant::No, should_compute_role);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/accname-1.2/#mapping_additional_nd_description
|
||||
|
|
|
@ -58,6 +58,11 @@ enum class IsDescendant {
|
|||
Yes,
|
||||
};
|
||||
|
||||
enum class ShouldComputeRole {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
#define ENUMERATE_STYLE_INVALIDATION_REASONS(X) \
|
||||
X(ActiveElementChange) \
|
||||
X(AdoptedStyleSheetsList) \
|
||||
|
@ -732,7 +737,7 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
ErrorOr<String> accessible_name(Document const&) const;
|
||||
ErrorOr<String> accessible_name(Document const&, ShouldComputeRole = ShouldComputeRole::Yes) const;
|
||||
ErrorOr<String> accessible_description(Document const&) const;
|
||||
|
||||
Optional<String> locate_a_namespace(Optional<String> const& prefix) const;
|
||||
|
@ -765,7 +770,7 @@ protected:
|
|||
|
||||
void build_accessibility_tree(AccessibilityTreeNode& parent);
|
||||
|
||||
ErrorOr<String> name_or_description(NameOrDescription, Document const&, HashTable<UniqueNodeID>&, IsDescendant = IsDescendant::No) const;
|
||||
ErrorOr<String> name_or_description(NameOrDescription, Document const&, HashTable<UniqueNodeID>&, IsDescendant = IsDescendant::No, ShouldComputeRole = ShouldComputeRole::Yes) const;
|
||||
|
||||
private:
|
||||
void queue_tree_mutation_record(Vector<GC::Root<Node>> added_nodes, Vector<GC::Root<Node>> removed_nodes, Node* previous_sibling, Node* next_sibling);
|
||||
|
|
Loading…
Reference in a new issue