From 1b165d887bec38ccdd453ba06efc65951b7d8ea1 Mon Sep 17 00:00:00 2001 From: sideshowbarker Date: Mon, 16 Dec 2024 18:54:50 +0900 Subject: [PATCH] =?UTF-8?q?LibWeb:=20Support=20the=20ARIA=20=E2=80=9Csecti?= =?UTF-8?q?onheader=E2=80=9D=20&=20=E2=80=9Csectionfooter=E2=80=9D=20roles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Libraries/LibWeb/ARIA/AriaRoles.json | 92 +++++++++++++++++++ Libraries/LibWeb/ARIA/RoleType.cpp | 4 + Libraries/LibWeb/ARIA/Roles.h | 2 + Libraries/LibWeb/HTML/HTMLElement.cpp | 14 ++- .../html-aam/roles-contextual.tentative.txt | 9 ++ .../html-aam/roles-contextual.tentative.html | 36 ++++++++ 6 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html-aam/roles-contextual.tentative.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html-aam/roles-contextual.tentative.html diff --git a/Libraries/LibWeb/ARIA/AriaRoles.json b/Libraries/LibWeb/ARIA/AriaRoles.json index 4bd5ec34538..bb11cf378c9 100644 --- a/Libraries/LibWeb/ARIA/AriaRoles.json +++ b/Libraries/LibWeb/ARIA/AriaRoles.json @@ -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.", diff --git a/Libraries/LibWeb/ARIA/RoleType.cpp b/Libraries/LibWeb/ARIA/RoleType.cpp index ceba11dc0fc..891e15bb85c 100644 --- a/Libraries/LibWeb/ARIA/RoleType.cpp +++ b/Libraries/LibWeb/ARIA/RoleType.cpp @@ -282,6 +282,10 @@ ErrorOr> 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)); diff --git a/Libraries/LibWeb/ARIA/Roles.h b/Libraries/LibWeb/ARIA/Roles.h index 1ce01d8cc87..193fe9ac66c 100644 --- a/Libraries/LibWeb/ARIA/Roles.h +++ b/Libraries/LibWeb/ARIA/Roles.h @@ -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) \ diff --git a/Libraries/LibWeb/HTML/HTMLElement.cpp b/Libraries/LibWeb/HTML/HTMLElement.cpp index 4321db9997a..35a412fdcb0 100644 --- a/Libraries/LibWeb/HTML/HTMLElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLElement.cpp @@ -766,10 +766,16 @@ Optional 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) diff --git a/Tests/LibWeb/Text/expected/wpt-import/html-aam/roles-contextual.tentative.txt b/Tests/LibWeb/Text/expected/wpt-import/html-aam/roles-contextual.tentative.txt new file mode 100644 index 00000000000..3a8f388f03b --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html-aam/roles-contextual.tentative.txt @@ -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 \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/html-aam/roles-contextual.tentative.html b/Tests/LibWeb/Text/input/wpt-import/html-aam/roles-contextual.tentative.html new file mode 100644 index 00000000000..6119efa40a9 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/html-aam/roles-contextual.tentative.html @@ -0,0 +1,36 @@ + + + + Tentative: HTML-AAM Contextual-Specific Role Verification Tests + + + + + + + + + + + +
+
x
+
+ +
+
x
+
+ + + + + \ No newline at end of file