[feat] add a11y check on abstract roles (#6241)

* add a11y check on abstract roles

* use aria-query and move warnings to compiler_warnings file

* uppercase warning message

Co-authored-by: tanhauhau <lhtan93@gmail.com>
pull/7679/head
Anthony Le Goas 2 years ago committed by GitHub
parent ccbf10c163
commit f5111ef436
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -107,6 +107,10 @@ export default {
code: 'a11y-unknown-role',
message: `A11y: Unknown role '${role}'` + (suggestion ? ` (did you mean '${suggestion}'?)` : '')
}),
a11y_no_abstract_role: (role: string | boolean) => ({
code: 'a11y-no-abstract-role',
message: `A11y: Abstract role '${role}' is forbidden`
}),
a11y_no_redundant_roles: (role: string | boolean) => ({
code: 'a11y-no-redundant-roles',
message: `A11y: Redundant role '${role}'`

@ -32,6 +32,7 @@ const aria_attribute_set = new Set(aria_attributes);
const aria_roles = 'alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox complementary contentinfo definition deletion dialog directory document emphasis feed figure form generic graphics-document graphics-object graphics-symbol grid gridcell group heading img link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup region row rowgroup rowheader scrollbar search searchbox separator slider spinbutton status strong subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem'.split(' ');
const aria_role_set = new Set(aria_roles);
const aria_role_abstract_set = new Set(roles.keys().filter(role => roles.get(role).abstract));
const a11y_required_attributes = {
a: ['href'],
@ -479,8 +480,10 @@ export default class Element extends Node {
}
const value = attribute.get_static_value();
// @ts-ignore
if (value && !aria_role_set.has(value)) {
if (value && aria_role_abstract_set.has(value as ARIARoleDefintionKey)) {
component.warn(attribute, compiler_warnings.a11y_no_abstract_role(value));
} else if (value && !aria_role_set.has(value as string)) {
// @ts-ignore
const match = fuzzymatch(value, aria_roles);
component.warn(attribute, compiler_warnings.a11y_unknown_role(value, match));

@ -0,0 +1,12 @@
<div role="command"/>
<div role="composite"/>
<div role="input"/>
<div role="landmark"/>
<div role="range"/>
<div role="roletype"/>
<div role="section"/>
<div role="sectionhead"/>
<div role="select"/>
<div role="structure"/>
<div role="widget"/>
<div role="window"/>

@ -0,0 +1,182 @@
[
{
"code": "a11y-no-abstract-role",
"end": {
"character": 19,
"column": 19,
"line": 1
},
"message": "A11y: Abstract role 'command' is forbidden",
"pos": 5,
"start": {
"character": 5,
"column": 5,
"line": 1
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 43,
"column": 21,
"line": 2
},
"message": "A11y: Abstract role 'composite' is forbidden",
"pos": 27,
"start": {
"character": 27,
"column": 5,
"line": 2
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 63,
"column": 17,
"line": 3
},
"message": "A11y: Abstract role 'input' is forbidden",
"pos": 51,
"start": {
"character": 51,
"column": 5,
"line": 3
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 86,
"column": 20,
"line": 4
},
"message": "A11y: Abstract role 'landmark' is forbidden",
"pos": 71,
"start": {
"character": 71,
"column": 5,
"line": 4
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 106,
"column": 17,
"line": 5
},
"message": "A11y: Abstract role 'range' is forbidden",
"pos": 94,
"start": {
"character": 94,
"column": 5,
"line": 5
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 129,
"column": 20,
"line": 6
},
"message": "A11y: Abstract role 'roletype' is forbidden",
"pos": 114,
"start": {
"character": 114,
"column": 5,
"line": 6
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 151,
"column": 19,
"line": 7
},
"message": "A11y: Abstract role 'section' is forbidden",
"pos": 137,
"start": {
"character": 137,
"column": 5,
"line": 7
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 177,
"column": 23,
"line": 8
},
"message": "A11y: Abstract role 'sectionhead' is forbidden",
"pos": 159,
"start": {
"character": 159,
"column": 5,
"line": 8
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 198,
"column": 18,
"line": 9
},
"message": "A11y: Abstract role 'select' is forbidden",
"pos": 185,
"start": {
"character": 185,
"column": 5,
"line": 9
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 222,
"column": 21,
"line": 10
},
"message": "A11y: Abstract role 'structure' is forbidden",
"pos": 206,
"start": {
"character": 206,
"column": 5,
"line": 10
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 243,
"column": 18,
"line": 11
},
"message": "A11y: Abstract role 'widget' is forbidden",
"pos": 230,
"start": {
"character": 230,
"column": 5,
"line": 11
}
},
{
"code": "a11y-no-abstract-role",
"end": {
"character": 264,
"column": 18,
"line": 12
},
"message": "A11y: Abstract role 'window' is forbidden",
"pos": 251,
"start": {
"character": 251,
"column": 5,
"line": 12
}
}
]
Loading…
Cancel
Save