mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 11:36:10 +00:00
LibWeb: Update ARIA default-role handling for img, section, and aside
This change updates our handling of computation for default ARIA roles for the img, section, and aside elements to match the expectations in the updated WPT test at http://wpt.live/html-aam/roles-contextual.html.
This commit is contained in:
parent
6b9e8cf40c
commit
fdcb27749d
5 changed files with 90 additions and 22 deletions
|
@ -2470,16 +2470,14 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
// 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.
|
||||
// https://github.com/w3c/aria/issues/2404
|
||||
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
|
||||
// element or section element 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, we only compute a default role here if this
|
||||
// isn’t an aside element or section element.
|
||||
// Per-spec, at https://w3c.github.io/html-aam/#el-aside and elsewhere, computing a default role for certain
|
||||
// elements (img, aside, and section) requires first computing its accessible name. So to avoid getting into an
|
||||
// infinite loop here, the callers in our code for those cases pass in ShouldComputeRole::Yes.
|
||||
// https://github.com/w3c/aria/issues/2391
|
||||
if (!role.has_value() && element->local_name() != HTML::TagNames::aside && element->local_name() != HTML::TagNames::section)
|
||||
if (should_compute_role == ShouldComputeRole::Yes && !role.has_value())
|
||||
role = element->default_role();
|
||||
|
||||
// 2. Compute the text alternative for the current node:
|
||||
|
@ -2550,7 +2548,7 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
total_accumulated_text.append(result);
|
||||
}
|
||||
|
||||
// iii. Return the accumulated text.
|
||||
// iii. Return the accumulated text if it is not the empty string ("").
|
||||
// AD-HOC: This substep in the spec doesn’t seem to explicitly require the following check for an aria-label
|
||||
// value; but the “button's hidden referenced name (visibility:hidden) with hidden aria-labelledby traversal
|
||||
// falls back to aria-label” subtest at https://wpt.fyi/results/accname/name/comp_labelledby.html won’t pass
|
||||
|
@ -2675,7 +2673,9 @@ ErrorOr<String> Node::name_or_description(NameOrDescription target, Document con
|
|||
//
|
||||
// https://w3c.github.io/html-aam/#img-element-accessible-name-computation
|
||||
// use alt attribute, even if its value is the empty string.
|
||||
// See also https://wpt.fyi/results/accname/name/comp_tooltip.tentative.html.
|
||||
// See also https://wpt.fyi/results/accname/name/comp_tooltip.tentative.html — but also see
|
||||
// https://github.com/w3c/aria/issues/2491 and the el-img-empty-alt-title subtest in the test at
|
||||
// https://wpt.fyi/results/html-aam/roles-contextual.html.
|
||||
if (is<HTML::HTMLImageElement>(*element) && element->has_attribute(HTML::AttributeNames::alt))
|
||||
return element->get_attribute(HTML::AttributeNames::alt).value();
|
||||
|
||||
|
|
|
@ -845,7 +845,7 @@ Optional<ARIA::Role> HTMLElement::default_role() const
|
|||
// https://w3c.github.io/html-aam/#el-aside
|
||||
for (auto const* ancestor = parent_element(); ancestor; ancestor = ancestor->parent_element()) {
|
||||
if (ancestor->local_name().is_one_of(TagNames::article, TagNames::aside, TagNames::nav, TagNames::section)
|
||||
&& accessible_name(document()).value().is_empty())
|
||||
&& accessible_name(document(), DOM::ShouldComputeRole::No).value().trim_whitespace(TrimMode::Both).value().is_empty())
|
||||
return ARIA::Role::generic;
|
||||
}
|
||||
// https://w3c.github.io/html-aam/#el-aside-ancestorbodymain
|
||||
|
@ -932,7 +932,7 @@ Optional<ARIA::Role> HTMLElement::default_role() const
|
|||
// https://www.w3.org/TR/html-aria/#el-section
|
||||
if (local_name() == TagNames::section) {
|
||||
// role=region if the section element has an accessible name
|
||||
if (!accessible_name(document()).value().is_empty())
|
||||
if (!accessible_name(document(), DOM::ShouldComputeRole::No).value().trim_whitespace(TrimMode::Both).value().is_empty())
|
||||
return ARIA::Role::region;
|
||||
// Otherwise, role=generic
|
||||
return ARIA::Role::generic;
|
||||
|
|
|
@ -418,17 +418,18 @@ WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> HTMLImageElement::decode() const
|
|||
|
||||
Optional<ARIA::Role> HTMLImageElement::default_role() const
|
||||
{
|
||||
// https://www.w3.org/TR/html-aria/#el-img-empty-alt
|
||||
// NOTE: The "none" role value is a synonym for the older "presentation" role value; however, the el-img-alt-no-value
|
||||
// test in https://wpt.fyi/results/html-aam/roles.html expects the value to be "none" (not "presentation").
|
||||
if (has_attribute(HTML::AttributeNames::alt) && alt().is_empty()
|
||||
&& accessible_name(document(), DOM::ShouldComputeRole::No).value().trim_whitespace(TrimMode::Both).value().is_empty())
|
||||
return ARIA::Role::none;
|
||||
// https://www.w3.org/TR/html-aria/#el-img
|
||||
// https://www.w3.org/TR/html-aria/#el-img-no-alt
|
||||
// https://w3c.github.io/aria/#image
|
||||
// NOTE: The "image" role value is a synonym for the older "img" role value; however, the el-img test in
|
||||
// https://wpt.fyi/results/html-aam/roles.html expects the value to be "image" (not "img").
|
||||
if (!alt().is_empty())
|
||||
return ARIA::Role::image;
|
||||
// https://www.w3.org/TR/html-aria/#el-img-empty-alt
|
||||
// NOTE: The "none" role value is a synonym for the older "presentation" role value; however, the el-img-alt-no-value
|
||||
// test in https://wpt.fyi/results/html-aam/roles.html expects the value to be "none" (not "presentation").
|
||||
return ARIA::Role::none;
|
||||
return ARIA::Role::image;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/images.html#use-srcset-or-picture
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 19 tests
|
||||
Found 48 tests
|
||||
|
||||
19 Pass
|
||||
47 Pass
|
||||
1 Fail
|
||||
Pass el-a
|
||||
Pass el-aside
|
||||
Pass el-aside-in-main
|
||||
|
@ -12,13 +13,42 @@ Pass el-aside-in-aside-with-name
|
|||
Pass el-aside-in-nav-with-name
|
||||
Pass el-aside-in-nav-with-role
|
||||
Pass el-aside-in-section-with-name
|
||||
Pass el-aside-in-section-aria-labelledby
|
||||
Pass el-aside-in-section-title
|
||||
Pass el-footer-ancestorbody
|
||||
Pass el-header-ancestorbody
|
||||
Pass el-img-no-name
|
||||
Pass el-img-empty-alt-aria-label
|
||||
Pass el-img-empty-alt-aria-labelledby
|
||||
Fail el-img-empty-alt-title
|
||||
Pass el-section
|
||||
Pass el-section-aria-labelledby
|
||||
Pass el-section-title
|
||||
Pass el-a-no-href
|
||||
Pass el-aside-in-article-in-main
|
||||
Pass el-aside-in-article
|
||||
Pass el-aside-in-aside
|
||||
Pass el-aside-in-nav
|
||||
Pass el-aside-in-section
|
||||
Pass el-section-no-name
|
||||
Pass el-aside-in-section-aria-label-empty
|
||||
Pass el-aside-in-section-aria-label-whitespace
|
||||
Pass el-aside-in-section-aria-labelledby-non-existing
|
||||
Pass el-aside-in-section-aria-labelledby-empty
|
||||
Pass el-aside-in-section-aria-labelledby-whitespace
|
||||
Pass el-aside-in-section-title-empty
|
||||
Pass el-aside-in-section-title-whitespace
|
||||
Pass el-img-empty-alt-aria-label-empty
|
||||
Pass el-img-empty-alt-aria-label-whitespace
|
||||
Pass el-img-empty-alt-aria-labelledby-non-existing
|
||||
Pass el-img-empty-alt-aria-labelledby-empty
|
||||
Pass el-img-empty-alt-aria-labelledby-whitespace
|
||||
Pass el-img-empty-alt-title-empty
|
||||
Pass el-img-empty-alt-title-whitespace
|
||||
Pass el-section-no-name
|
||||
Pass el-section-aria-label-empty
|
||||
Pass el-section-aria-label-whitespace
|
||||
Pass el-section-aria-labelledby-non-existing
|
||||
Pass el-section-aria-labelledby-empty
|
||||
Pass el-section-aria-labelledby-whitespace
|
||||
Pass el-section-title-empty
|
||||
Pass el-section-title-whitespace
|
|
@ -12,7 +12,7 @@
|
|||
<body>
|
||||
|
||||
|
||||
<p>Tests contextual computedrole mappings defined in <a href="https://w3c.github.io/html-aam/">HTML-AAM</a>, where the returned computed role is expected to change based on the context. Most test names correspond to a unique ID defined in the spec.<p>
|
||||
<p>Tests contextual computed role mappings defined in <a href="https://w3c.github.io/html-aam/">HTML-AAM</a>, where the returned computed role is expected to change based on the context. Most test names correspond to a unique ID defined in the spec.<p>
|
||||
|
||||
<p>These should remain in alphabetical order.</code></p>
|
||||
|
||||
|
@ -50,6 +50,15 @@
|
|||
<section aria-label="x">
|
||||
<aside data-testname="el-aside-in-section" class="ex-generic">x</aside>
|
||||
<aside data-testname="el-aside-in-section-with-name" data-expectedrole="complementary" aria-label="x" class="ex">x</aside>
|
||||
<aside data-testname="el-aside-in-section-aria-label-empty" class="ex-generic" aria-label="">x</aside>
|
||||
<aside data-testname="el-aside-in-section-aria-label-whitespace" class="ex-generic" aria-label=" ">x</aside>
|
||||
<aside data-testname="el-aside-in-section-aria-labelledby" data-expectedrole="complementary" class="ex" aria-labelledby="labelledby">x</aside>
|
||||
<aside data-testname="el-aside-in-section-aria-labelledby-non-existing" class="ex-generic" aria-labelledby="non-existing">x</aside>
|
||||
<aside data-testname="el-aside-in-section-aria-labelledby-empty" class="ex-generic" aria-labelledby="empty">x</aside>
|
||||
<aside data-testname="el-aside-in-section-aria-labelledby-whitespace" class="ex-generic" aria-labelledby="space">x</aside>
|
||||
<aside data-testname="el-aside-in-section-title" data-expectedrole="complementary" title="x" class="ex">x</aside>
|
||||
<aside data-testname="el-aside-in-section-title-empty" class="ex-generic" title="">x</aside>
|
||||
<aside data-testname="el-aside-in-section-title-whitespace" class="ex-generic" title=" ">x</aside>
|
||||
</section>
|
||||
|
||||
<!-- el-footer -->
|
||||
|
@ -62,10 +71,38 @@
|
|||
<header data-testname="el-header-ancestorbody" data-expectedrole="banner" class="ex">x</header>
|
||||
<!-- main>header -> ./roles-contextual.tentative.html -->
|
||||
|
||||
<!-- el-img-empty-alt -->
|
||||
<img data-testname="el-img-no-name" data-expectedrole="image" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==">
|
||||
<!-- img empty alt -> ./roles.html -->
|
||||
<img data-testname="el-img-empty-alt-aria-label" data-expectedrole="image" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-label="x">
|
||||
<img data-testname="el-img-empty-alt-aria-label-empty" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-label="">
|
||||
<img data-testname="el-img-empty-alt-aria-label-whitespace" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-label=" ">
|
||||
<img data-testname="el-img-empty-alt-aria-labelledby" data-expectedrole="image" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-labelledby="labelledby">
|
||||
<img data-testname="el-img-empty-alt-aria-labelledby-non-existing" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-labelledby="non-existing">
|
||||
<img data-testname="el-img-empty-alt-aria-labelledby-empty" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-labelledby="empty">
|
||||
<img data-testname="el-img-empty-alt-aria-labelledby-whitespace" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt aria-labelledby="space">
|
||||
<img data-testname="el-img-empty-alt-title" data-expectedrole="image" class="ex" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt title="x">
|
||||
<img data-testname="el-img-empty-alt-title-empty" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt title="">
|
||||
<img data-testname="el-img-empty-alt-title-whitespace" class="ex-generic" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" alt title=" ">
|
||||
|
||||
|
||||
<!-- el-section -->
|
||||
<section data-testname="el-section" aria-label="x" data-expectedrole="region" class="ex">x</section>
|
||||
<section data-testname="el-section-no-name" class="ex-generic">x</section>
|
||||
<section data-testname="el-section-aria-label-empty" class="ex-generic" aria-label="">x</section>
|
||||
<section data-testname="el-section-aria-label-whitespace" class="ex-generic" aria-label=" ">x</section>
|
||||
<section data-testname="el-section-aria-labelledby" data-expectedrole="region" class="ex" aria-labelledby="labelledby">x</section>
|
||||
<section data-testname="el-section-aria-labelledby-non-existing" class="ex-generic" aria-labelledby="non-existing">x</section>
|
||||
<section data-testname="el-section-aria-labelledby-empty" class="ex-generic" aria-labelledby="empty">x</section>
|
||||
<section data-testname="el-section-aria-labelledby-whitespace" class="ex-generic" aria-labelledby="space">x</section>
|
||||
<section data-testname="el-section-title" data-expectedrole="region" title="x" class="ex">x</section>
|
||||
<section data-testname="el-section-title-empty" class="ex-generic" title="">x</section>
|
||||
<section data-testname="el-section-title-whitespace" class="ex-generic" title=" ">x</section>
|
||||
|
||||
<!-- element to reference for aria-labelledby tests -->
|
||||
<div id="labelledby">labelledby</div>
|
||||
<div id="empty"></div>
|
||||
<div id="space"> </div>
|
||||
|
||||
<script>
|
||||
AriaUtils.verifyRolesBySelector(".ex");
|
||||
|
@ -73,4 +110,4 @@ AriaUtils.verifyGenericRolesBySelector(".ex-generic");
|
|||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Reference in a new issue