LibWeb: Support the ARIA “sectionheader” & “sectionfooter” roles

This commit is contained in:
sideshowbarker 2024-12-16 18:54:50 +09:00 committed by Tim Flynn
parent 203267fcc2
commit 1b165d887b
Notes: github-actions[bot] 2024-12-16 14:57:25 +00:00
6 changed files with 153 additions and 4 deletions

View file

@ -496,6 +496,98 @@
"childrenArePresentational": false,
"implicitValueForRole": {}
},
"SectionFooter": {
"specLink": "https://w3c.github.io/aria/#sectionfooter",
"description": "A set of user interface objects and information representing information about its closest ancestral content group.",
"superClassRoles": [
"Section"
],
"supportedStates": [
"aria-busy",
"aria-current",
"aria-disabled",
"aria-grabbed",
"aria-hidden",
"aria-invalid"
],
"supportedProperties": [
"aria-atomic",
"aria-braillelabel",
"aria-brailleroledescription",
"aria-controls",
"aria-describedby",
"aria-description",
"aria-details",
"aria-dropeffect",
"aria-dropeffect",
"aria-errormessage",
"aria-flowto",
"aria-haspopup",
"aria-keyshortcuts",
"aria-label",
"aria-labelledby",
"aria-live",
"aria-owns",
"aria-relevant",
"aria-roledescription"
],
"requiredStates": [],
"requiredProperties": [],
"prohibitedStates": [],
"prohibitedProperties": [],
"requiredContextRoles": [],
"requiredOwnedElements": [],
"nameFromSource": "Author",
"accessibleNameRequired": false,
"childrenArePresentational": false,
"implicitValueForRole": {}
},
"SectionHeader": {
"specLink": "https://w3c.github.io/aria/#sectionheader",
"description": "A set of user interface objects and information that represents a collection of introductory items for the element's closest ancestral content group.",
"superClassRoles": [
"Section"
],
"supportedStates": [
"aria-busy",
"aria-current",
"aria-disabled",
"aria-grabbed",
"aria-hidden",
"aria-invalid"
],
"supportedProperties": [
"aria-atomic",
"aria-braillelabel",
"aria-brailleroledescription",
"aria-controls",
"aria-describedby",
"aria-description",
"aria-details",
"aria-dropeffect",
"aria-dropeffect",
"aria-errormessage",
"aria-flowto",
"aria-haspopup",
"aria-keyshortcuts",
"aria-label",
"aria-labelledby",
"aria-live",
"aria-owns",
"aria-relevant",
"aria-roledescription"
],
"requiredStates": [],
"requiredProperties": [],
"prohibitedStates": [],
"prohibitedProperties": [],
"requiredContextRoles": [],
"requiredOwnedElements": [],
"nameFromSource": "Author",
"accessibleNameRequired": false,
"childrenArePresentational": false,
"implicitValueForRole": {}
},
"Input": {
"specLink": "https://www.w3.org/TR/wai-aria-1.2/#input",
"description": "A generic type of widget that allows user input.",

View file

@ -282,6 +282,10 @@ ErrorOr<NonnullOwnPtr<RoleType>> RoleType::build_role_object(Role role, bool foc
return adopt_nonnull_own_or_enomem(new (nothrow) Search(data));
case Role::searchbox:
return adopt_nonnull_own_or_enomem(new (nothrow) SearchBox(data));
case Role::sectionfooter:
return adopt_nonnull_own_or_enomem(new (nothrow) SectionFooter(data));
case Role::sectionheader:
return adopt_nonnull_own_or_enomem(new (nothrow) SectionHeader(data));
case Role::separator:
if (focusable)
return adopt_nonnull_own_or_enomem(new (nothrow) FocusableSeparator(data));

View file

@ -82,7 +82,9 @@ namespace Web::ARIA {
__ENUMERATE_ARIA_ROLE(search) \
__ENUMERATE_ARIA_ROLE(searchbox) \
__ENUMERATE_ARIA_ROLE(section) \
__ENUMERATE_ARIA_ROLE(sectionfooter) \
__ENUMERATE_ARIA_ROLE(sectionhead) \
__ENUMERATE_ARIA_ROLE(sectionheader) \
__ENUMERATE_ARIA_ROLE(select) \
__ENUMERATE_ARIA_ROLE(separator) \
__ENUMERATE_ARIA_ROLE(slider) \

View file

@ -766,10 +766,16 @@ Optional<ARIA::Role> HTMLElement::default_role() const
// complementary, main, navigation or region then (footer) role=contentinfo (header) role=banner. Otherwise,
// role=generic.
for (auto const* ancestor = parent_element(); ancestor; ancestor = ancestor->parent_element()) {
if (first_is_one_of(ancestor->local_name(), TagNames::article, TagNames::aside, TagNames::main, TagNames::nav, TagNames::section))
return ARIA::Role::generic;
if (first_is_one_of(ancestor->role_or_default(), ARIA::Role::article, ARIA::Role::complementary, ARIA::Role::main, ARIA::Role::navigation, ARIA::Role::region))
return ARIA::Role::generic;
if (first_is_one_of(ancestor->local_name(), TagNames::article, TagNames::aside, TagNames::main, TagNames::nav, TagNames::section)) {
if (local_name() == TagNames::footer)
return ARIA::Role::sectionfooter;
return ARIA::Role::sectionheader;
}
if (first_is_one_of(ancestor->role_or_default(), ARIA::Role::article, ARIA::Role::complementary, ARIA::Role::main, ARIA::Role::navigation, ARIA::Role::region)) {
if (local_name() == TagNames::footer)
return ARIA::Role::sectionfooter;
return ARIA::Role::sectionheader;
}
}
// then (footer) role=contentinfo.
if (local_name() == TagNames::footer)

View file

@ -0,0 +1,9 @@
Harness status: OK
Found 4 tests
4 Pass
Pass el-footer
Pass el-footer-ancestormain
Pass el-header
Pass el-header-ancestormain

View file

@ -0,0 +1,36 @@
<!doctype html>
<html>
<head>
<title>Tentative: HTML-AAM Contextual-Specific Role Verification Tests</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/testdriver.js"></script>
<script src="../resources/testdriver-vendor.js"></script>
<script src="../resources/testdriver-actions.js"></script>
<script src="../wai-aria/scripts/aria-utils.js"></script>
</head>
<body>
<!--
New sectionheader and sectionfooter roles.
See https://github.com/w3c/aria/pull/1931
-->
<nav>
<footer data-testname="el-footer" aria-label="x" data-expectedrole="sectionfooter" class="ex">x</aside>
</nav>
<main>
<footer data-testname="el-footer-ancestormain" data-expectedrole="sectionfooter" class="ex">x</footer>
</main>
<nav>
<header data-testname="el-header" aria-label="x" data-expectedrole="sectionheader" class="ex">x</header>
</nav>
<main>
<header data-testname="el-header-ancestormain" data-expectedrole="sectionheader" class="ex">x</header>
</main>
<script>
AriaUtils.verifyRolesBySelector(".ex");
</script>
</body>
</html>