Bläddra i källkod

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 do not have accessible names as required, UAs must
treat them as if they’d not be specified at all.
sideshowbarker 6 månader sedan
förälder
incheckning
fe2408c44b

+ 9 - 0
Libraries/LibWeb/ARIA/ARIAMixin.cpp

@@ -7,6 +7,7 @@
 #include <LibWeb/ARIA/ARIAMixin.h>
 #include <LibWeb/ARIA/Roles.h>
 #include <LibWeb/DOM/Element.h>
+#include <LibWeb/DOM/Node.h>
 #include <LibWeb/Infra/CharacterTypes.h>
 
 namespace Web::ARIA {
@@ -130,6 +131,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;

+ 17 - 0
Tests/LibWeb/Text/expected/wpt-import/wai-aria/role/fallback-roles.txt

@@ -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

+ 7 - 0
Tests/LibWeb/Text/expected/wpt-import/wai-aria/role/form-roles.txt

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

+ 7 - 0
Tests/LibWeb/Text/expected/wpt-import/wai-aria/role/region-roles.txt

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

+ 57 - 0
Tests/LibWeb/Text/input/wpt-import/wai-aria/role/fallback-roles.html

@@ -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>

+ 28 - 0
Tests/LibWeb/Text/input/wpt-import/wai-aria/role/form-roles.html

@@ -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>

+ 27 - 0
Tests/LibWeb/Text/input/wpt-import/wai-aria/role/region-roles.html

@@ -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>