Coverage Report

Created: 2025-09-05 06:52

/src/serenity/Userland/Libraries/LibWeb/ARIA/Roles.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2022, Jonah Shafran <jonahshafran@gmail.com>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
#include <AK/GenericShorthands.h>
8
#include <LibWeb/ARIA/Roles.h>
9
10
namespace Web::ARIA {
11
12
StringView role_name(Role role)
13
0
{
14
    // Note: Role::switch_ is mapped to "switch" (due to C++ keyword clash)
15
0
    switch (role) {
16
0
#define __ENUMERATE_ARIA_ROLE(name)                \
17
0
    case Role::name:                               \
18
0
        if constexpr (Role::name == Role::switch_) \
19
0
            return "switch"sv;                     \
20
0
        return #name##sv;
21
0
        ENUMERATE_ARIA_ROLES
22
0
#undef __ENUMERATE_ARIA_ROLE
23
0
    default:
24
0
        VERIFY_NOT_REACHED();
25
0
    }
26
0
}
27
28
Optional<Role> role_from_string(StringView role_name)
29
0
{
30
    // Note: "switch" is mapped to Role::switch_ (due to C++ keyword clash)
31
0
#define __ENUMERATE_ARIA_ROLE(name)                           \
32
0
    if constexpr (Role::name == Role::switch_) {              \
33
0
        if (role_name.equals_ignoring_ascii_case("switch"sv)) \
34
0
            return Role::switch_;                             \
35
0
    } else {                                                  \
36
0
        if (role_name.equals_ignoring_ascii_case(#name##sv))  \
37
0
            return Role::name;                                \
38
0
    }
39
0
    ENUMERATE_ARIA_ROLES
40
0
#undef __ENUMERATE_ARIA_ROLE
41
0
    return {};
42
0
}
43
44
// https://www.w3.org/TR/wai-aria-1.2/#abstract_roles
45
bool is_abstract_role(Role role)
46
0
{
47
0
    return first_is_one_of(role,
48
0
        Role::command,
49
0
        Role::composite,
50
0
        Role::input,
51
0
        Role::landmark,
52
0
        Role::range,
53
0
        Role::roletype,
54
0
        Role::section,
55
0
        Role::sectionhead,
56
0
        Role::select,
57
0
        Role::structure,
58
0
        Role::widget,
59
0
        Role::window);
60
0
}
61
62
// https://www.w3.org/TR/wai-aria-1.2/#widget_roles
63
bool is_widget_role(Role role)
64
0
{
65
0
    return first_is_one_of(role,
66
0
        Role::button,
67
0
        Role::checkbox,
68
0
        Role::gridcell,
69
0
        Role::link,
70
0
        Role::menuitem,
71
0
        Role::menuitemcheckbox,
72
0
        Role::menuitemradio,
73
0
        Role::option,
74
0
        Role::progressbar,
75
0
        Role::radio,
76
0
        Role::scrollbar,
77
0
        Role::searchbox,
78
0
        Role::separator, // TODO: Only when focusable
79
0
        Role::slider,
80
0
        Role::spinbutton,
81
0
        Role::switch_,
82
0
        Role::tab,
83
0
        Role::tabpanel,
84
0
        Role::textbox,
85
0
        Role::treeitem,
86
0
        Role::combobox,
87
0
        Role::grid,
88
0
        Role::listbox,
89
0
        Role::menu,
90
0
        Role::menubar,
91
0
        Role::radiogroup,
92
0
        Role::tablist,
93
0
        Role::tree,
94
0
        Role::treegrid);
95
0
}
96
97
// https://www.w3.org/TR/wai-aria-1.2/#document_structure_roles
98
bool is_document_structure_role(Role role)
99
0
{
100
0
    return first_is_one_of(role,
101
0
        Role::application,
102
0
        Role::article,
103
0
        Role::blockquote,
104
0
        Role::caption,
105
0
        Role::cell,
106
0
        Role::columnheader,
107
0
        Role::definition,
108
0
        Role::deletion,
109
0
        Role::directory,
110
0
        Role::document,
111
0
        Role::emphasis,
112
0
        Role::feed,
113
0
        Role::figure,
114
0
        Role::generic,
115
0
        Role::group,
116
0
        Role::heading,
117
0
        Role::img,
118
0
        Role::insertion,
119
0
        Role::list,
120
0
        Role::listitem,
121
0
        Role::math,
122
0
        Role::meter,
123
0
        Role::none,
124
0
        Role::note,
125
0
        Role::paragraph,
126
0
        Role::presentation,
127
0
        Role::row,
128
0
        Role::rowgroup,
129
0
        Role::rowheader,
130
0
        Role::separator, // TODO: Only when not focusable
131
0
        Role::strong,
132
0
        Role::subscript,
133
0
        Role::table,
134
0
        Role::term,
135
0
        Role::time,
136
0
        Role::toolbar,
137
0
        Role::tooltip);
138
0
}
139
140
// https://www.w3.org/TR/wai-aria-1.2/#landmark_roles
141
bool is_landmark_role(Role role)
142
0
{
143
0
    return first_is_one_of(role,
144
0
        Role::banner,
145
0
        Role::complementary,
146
0
        Role::contentinfo,
147
0
        Role::form,
148
0
        Role::main,
149
0
        Role::navigation,
150
0
        Role::region,
151
0
        Role::search);
152
0
}
153
154
// https://www.w3.org/TR/wai-aria-1.2/#live_region_roles
155
bool is_live_region_role(Role role)
156
0
{
157
0
    return first_is_one_of(role,
158
0
        Role::alert,
159
0
        Role::log,
160
0
        Role::marquee,
161
0
        Role::status,
162
0
        Role::timer);
163
0
}
164
165
// https://www.w3.org/TR/wai-aria-1.2/#window_roles
166
bool is_windows_role(Role role)
167
0
{
168
0
    return first_is_one_of(role,
169
0
        Role::alertdialog,
170
0
        Role::dialog);
171
0
}
172
173
bool is_non_abstract_role(Role role)
174
0
{
175
0
    return is_widget_role(role)
176
0
        || is_document_structure_role(role)
177
0
        || is_landmark_role(role)
178
0
        || is_live_region_role(role)
179
0
        || is_windows_role(role);
180
0
}
181
182
// https://www.w3.org/TR/wai-aria-1.2/#namefromcontent
183
bool allows_name_from_content(Role role)
184
0
{
185
0
    return first_is_one_of(role,
186
0
        Role::button,
187
0
        Role::cell,
188
0
        Role::checkbox,
189
0
        Role::columnheader,
190
0
        Role::gridcell,
191
0
        Role::heading,
192
0
        Role::link,
193
0
        Role::menuitem,
194
0
        Role::menuitemcheckbox,
195
0
        Role::menuitemradio,
196
0
        Role::option,
197
0
        Role::radio,
198
0
        Role::row,
199
0
        Role::rowheader,
200
0
        Role::sectionhead,
201
0
        Role::switch_,
202
0
        Role::tab,
203
0
        Role::tooltip,
204
0
        Role::treeitem);
205
0
}
206
207
}