mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-02 16:33:13 +00:00
LibWeb: Compute accessible names for hidden/hidden-but-referenced nodes
This change implements full support for the “A. Hidden Not Referenced” step at https://w3c.github.io/accname/#step2A in the “Accessible Name and Description Computation” spec — including handling all hidden nodes that must be ignored, as well as handling hidden nodes that, for the purposes of accessible-name computation, must not be ignored (due to having aria-labelledby/aria-describedby references from other nodes). Otherwise, without this change, not all cases of hidden nodes get ignored as expected, while cases of nodes that are hidden but that have aria-labelledby/aria-describedby references from other nodes get unexpectedly ignored.
This commit is contained in:
parent
c00b97a1f0
commit
314e5d6bb7
Notes:
github-actions[bot]
2024-11-29 12:19:31 +00:00
Author: https://github.com/sideshowbarker
Commit: 314e5d6bb7
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2294
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/gmta
Reviewed-by: https://github.com/yyny
7 changed files with 489 additions and 21 deletions
|
@ -1874,6 +1874,54 @@ void Element::invalidate_style_after_attribute_change(FlyString const& attribute
|
|||
invalidate_style(StyleInvalidationReason::ElementAttributeChange);
|
||||
}
|
||||
|
||||
bool Element::is_hidden() const
|
||||
{
|
||||
if (layout_node() == nullptr)
|
||||
return true;
|
||||
if (layout_node()->computed_values().visibility() == CSS::Visibility::Hidden || layout_node()->computed_values().visibility() == CSS::Visibility::Collapse || layout_node()->computed_values().content_visibility() == CSS::ContentVisibility::Hidden)
|
||||
return true;
|
||||
for (ParentNode const* self_or_ancestor = this; self_or_ancestor; self_or_ancestor = self_or_ancestor->parent_or_shadow_host()) {
|
||||
if (self_or_ancestor->is_element() && static_cast<DOM::Element const*>(self_or_ancestor)->aria_hidden() == "true")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Element::has_hidden_ancestor() const
|
||||
{
|
||||
for (ParentNode const* self_or_ancestor = this; self_or_ancestor; self_or_ancestor = self_or_ancestor->parent_or_shadow_host()) {
|
||||
if (self_or_ancestor->is_element() && static_cast<DOM::Element const*>(self_or_ancestor)->is_hidden())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Element::is_referenced() const
|
||||
{
|
||||
bool is_referenced = false;
|
||||
if (id().has_value()) {
|
||||
root().for_each_in_subtree_of_type<HTML::HTMLElement>([&](auto& element) {
|
||||
auto aria_data = MUST(Web::ARIA::AriaData::build_data(element));
|
||||
if (aria_data->aria_labelled_by_or_default().contains_slow(id().value())) {
|
||||
is_referenced = true;
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
}
|
||||
return is_referenced;
|
||||
}
|
||||
|
||||
bool Element::has_referenced_and_hidden_ancestor() const
|
||||
{
|
||||
for (auto const* ancestor = parent_or_shadow_host(); ancestor; ancestor = ancestor->parent_or_shadow_host()) {
|
||||
if (ancestor->is_element())
|
||||
if (auto const* element = static_cast<DOM::Element const*>(ancestor); element->is_referenced() && element->is_hidden())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
|
||||
bool Element::exclude_from_accessibility_tree() const
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue