LibWeb: Ignore name-required landmark roles which lack accessible names

This change implements the role-checking requirement from the ARIA spec
at https://w3c.github.io/aria/#document-handling_author-errors_roles
that the “form” and “region” roles are required to have accessible
names — and that if they don’t have accessible names as required, UAs
must treat them as if they’d not been specified at all.
This commit is contained in:
sideshowbarker 2024-12-19 23:34:18 +09:00 committed by Sam Atkins
parent 2cb7baa581
commit ead3af0163
Notes: github-actions[bot] 2025-01-09 14:09:37 +00:00
7 changed files with 151 additions and 0 deletions

View file

@ -130,6 +130,14 @@ Optional<Role> ARIAMixin::role_from_role_attribute_value() const
}
continue;
}
// https://w3c.github.io/aria/#document-handling_author-errors_roles
// Certain landmark roles require names from authors. In situations where an author has not specified names for
// these landmarks, it is considered an authoring error. The user agent MUST treat such elements as if no role
// had been provided. If a valid fallback role had been specified, or if the element had an implicit ARIA role,
// then user agents would continue to expose that role, instead.
if ((role == ARIA::Role::form || role == ARIA::Role::region)
&& to_element()->accessible_name(to_element()->document(), DOM::ShouldComputeRole::No).value().is_empty())
continue;
// 4. Use the first such substring in textual order that matches the name of a non-abstract WAI-ARIA role.
if (!is_abstract_role(*role))
return *role;

View file

@ -0,0 +1,17 @@
Harness status: OK
Found 12 tests
12 Pass
Pass fallback role w/ region with no label
Pass fallback role w/ region with label
Pass aria 1.1 switch role w/ fallback to aria 1.0 checkbox role
Pass div[role=button] ignoring invalid foo role token
Pass unknown[role=button] ignoring invalid foo role token
Pass button ignoring single invalid role token
Pass button ignoring multiple invalid role tokens
Pass div[role=button] ignoring invalid foo role token including punctuation-contaminated known link role
Pass div[role=button] ignoring invalid unicode diacritics etc on link and group role tokens
Pass div[role=button] ignoring tab char
Pass div[role=button] ignoring line break
Pass div[role=button] ignoring braille whitespace char

View file

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Pass
Pass form without label
Pass form with label

View file

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Pass
Pass region without label
Pass region with label

View file

@ -0,0 +1,57 @@
<!doctype html>
<html>
<head>
<title>Fallback 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>
<p>Tests <a href="https://w3c.github.io/aria/#host_general_role">8.1 Role Attribute</a> role token list selection and <a href="https://w3c.github.io/aria/#document-handling_author-errors_roles">9.1 Roles - handling author errors</a>.</p>
<!-- known el and two known ARIA 1.0 roles -->
<nav role="region group" data-testname="fallback role w/ region with no label" data-expectedrole="group" class="ex">x</nav>
<nav role="region group" data-testname="fallback role w/ region with label" aria-label="x" data-expectedrole="region" class="ex">x</nav>
<!-- known el and known ARIA 1.1 with 1.0 role backup -->
<div role="switch checkbox" aria-checked="true" data-testname="aria 1.1 switch role w/ fallback to aria 1.0 checkbox role" aria-label="x" data-expectedrole="switch" class="ex">x</div>
<!-- known el and invalid role token with valid backup -->
<div role="foo button" data-testname="div[role=button] ignoring invalid foo role token" aria-label="x" data-expectedrole="button" class="ex">x</div>
<!-- unknown el and invalid role token with valid backup -->
<unknown role="foo button" data-testname="unknown[role=button] ignoring invalid foo role token" aria-label="x" data-expectedrole="button" class="ex">x</unknown>
<!-- known el and invalid role(s) -->
<button role="foo" data-testname="button ignoring single invalid role token" aria-label="x" data-expectedrole="button" class="ex">x</unknown>
<button role="foo bar" data-testname="button ignoring multiple invalid role tokens" aria-label="x" data-expectedrole="button" class="ex">x</unknown>
<!-- known el with invalid punctuation -->
<div role="invalid, punctuation, tests, link, button" data-testname="div[role=button] ignoring invalid foo role token including punctuation-contaminated known link role" aria-label="x" data-expectedrole="button" class="ex">x</div>
<!-- extra line breaks here to account for rendering of unicode diacritic etc char glitch tests -->
<div role="l̷̨̢̡̖̻̗̤̺̟̱͚͔͇͍͇̫̫̜͔̗̟̘̫̟̰̼̘͗̌̃͐̔̈́̚͝į̵̡̲̯̠̮͈͖̥̮̲͓̦̗̗̱̞͍̗̪͙͇͚͂̍͐̔̍͌̐̇̏̎͘͝ǹ̶̨̧̢̜̲̫͇̮͉̬͎͎͕̝̱͔̙̱̦̰̦̠̰̣̝͂̓̋̊͜ķ̷̧̧̨̨̨̘̳͕̰͎̮̠̘̪͇͕̥̭̼̼̜̤̫̥̼̤̰̦͖̪̀͒̆͑̒̅͑̓̒͂̽̈́̽̉̀̕͘͜͝ ̷̡̮̦̘͓̫̜͕͖̰̙̘͓̼͎̳̹͇̮͐͂́͛̃́̊̈͌̄̓̌̂̈̇̀̌̈́́̀̈́̍̈́̇̄̊̔͒̾̾̇́͒̽͂̾̕̚͜͜͝͠ͅͅg̸̨̧̧̧̧̛̺̦̣͇͈͙͇͎͕̠̞̳̹̣͋͑̑̓͛̓̉̔̉͑̇́̈́̉̃́̑̍̂̒͐͛͗̑̏̓̾͌̈̅́̇̕̕̚̚͝͝ͅr̶̛̤̲̘̮̟̭̲̋̾̀́́̒̀̀͑̎̀̌̈̀̍̂̏̊̎͐͒͗͗̀͘͘͘͠͠ȍ̴̧̡̢̡̢̞̝̠̙̬̗͍͍͉̺͔͙̫̝̰̮̜̩̙̳͉̻̻̼͍̊͋͐̐͆̈̿̒̊̄͑̈́̔͋̔̃͐̓̓͛́͊̉͑̊̔͆͘͘͜͠ͅu̴̱̯̞̞̞̺̼̳̳͚̞̇̈͒͠p̶̛͉̮̙̯̮̱͉̖͚͉̩̱̺̩̦̺͈̫͍͔̲̣̗̟̜̂̐̌̏͌̈́͗̾͌̿̓͒̋̆͆̾͛̐̈́̓͋̀͘̚͝͝͝ ̶͔͚̩̬͈̍̈́͗͐̀̊̏͛̃̈́͋̅͝ button" data-testname="div[role=button] ignoring invalid unicode diacritics etc on link and group role tokens" aria-label="x" data-expectedrole="button" class="ex">x</div>
<!-- known el and known role with whitespace edge cases -->
<div role=" button" data-testname="div[role=button] ignoring tab char" aria-label="x" data-expectedrole="button" class="ex">x</div>
<div role="
button" data-testname="div[role=button] ignoring line break" aria-label="x" data-expectedrole="button" class="ex">x</div>
<div role=" button" data-testname="div[role=button] ignoring braille whitespace char" aria-label="x" data-expectedrole="button" class="ex">x</div>
<script>
AriaUtils.verifyRolesBySelector(".ex");
</script>
</body>
</html>

View file

@ -0,0 +1,28 @@
<!doctype html>
<html>
<head>
<title>Form 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>
<p>Verifies <a href="https://w3c.github.io/aria/#document-handling_author-errors_roles">9.1 Roles - handling author errors</a> and the <a href="https://w3c.github.io/aria/#form">form</a> role.</p>
<!-- no label -->
<nav role="form" data-testname="form without label" data-expectedrole="navigation" class="ex">x</nav>
<!-- w/ label -->
<nav role="form" data-testname="form with label" data-expectedrole="form" aria-label="x" class="ex">x</nav>
<script>
AriaUtils.verifyRolesBySelector(".ex");
</script>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!doctype html>
<html>
<head>
<title>Region 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>
<p>Tests <a href="https://w3c.github.io/aria/#region">region</a> and related roles, as well as the "name from author" rule in <a href="https://w3c.github.io/aria/#document-handling_author-errors_roles">9.1 Roles - handling author errors</a>.</p>
<!-- no label -->
<nav role="region" data-testname="region without label" data-expectedrole="navigation" class="ex">x</nav>
<!-- w/ label -->
<nav role="region" data-testname="region with label" data-expectedrole="region" aria-label="x" class="ex">x</nav>
<script>
AriaUtils.verifyRolesBySelector(".ex");
</script>
</body>
</html>