@@ -24,15 +24,14 @@ import { Literal } from 'estree';
24
24
import compiler_warnings from '../compiler_warnings' ;
25
25
import compiler_errors from '../compiler_errors' ;
26
26
import { ARIARoleDefintionKey , roles , aria , ARIAPropertyDefinition , ARIAProperty } from 'aria-query' ;
27
- import { noninteractive_roles } from '../utils/aria_roles' ;
28
- import { interactive_elements } from '../utils/elements' ;
27
+ import { is_interactive_element , is_non_interactive_roles , is_presentation_role } from '../utils/a11y' ;
29
28
30
29
const svg = / ^ (?: a l t G l y p h | a l t G l y p h D e f | a l t G l y p h I t e m | a n i m a t e | a n i m a t e C o l o r | a n i m a t e M o t i o n | a n i m a t e T r a n s f o r m | c i r c l e | c l i p P a t h | c o l o r - p r o f i l e | c u r s o r | d e f s | d e s c | d i s c a r d | e l l i p s e | f e B l e n d | f e C o l o r M a t r i x | f e C o m p o n e n t T r a n s f e r | f e C o m p o s i t e | f e C o n v o l v e M a t r i x | f e D i f f u s e L i g h t i n g | f e D i s p l a c e m e n t M a p | f e D i s t a n t L i g h t | f e D r o p S h a d o w | f e F l o o d | f e F u n c A | f e F u n c B | f e F u n c G | f e F u n c R | f e G a u s s i a n B l u r | f e I m a g e | f e M e r g e | f e M e r g e N o d e | f e M o r p h o l o g y | f e O f f s e t | f e P o i n t L i g h t | f e S p e c u l a r L i g h t i n g | f e S p o t L i g h t | f e T i l e | f e T u r b u l e n c e | f i l t e r | f o n t | f o n t - f a c e | f o n t - f a c e - f o r m a t | f o n t - f a c e - n a m e | f o n t - f a c e - s r c | f o n t - f a c e - u r i | f o r e i g n O b j e c t | g | g l y p h | g l y p h R e f | h a t c h | h a t c h p a t h | h k e r n | i m a g e | l i n e | l i n e a r G r a d i e n t | m a r k e r | m a s k | m e s h | m e s h g r a d i e n t | m e s h p a t c h | m e s h r o w | m e t a d a t a | m i s s i n g - g l y p h | m p a t h | p a t h | p a t t e r n | p o l y g o n | p o l y l i n e | r a d i a l G r a d i e n t | r e c t | s e t | s o l i d c o l o r | s t o p | s v g | s w i t c h | s y m b o l | t e x t | t e x t P a t h | t r e f | t s p a n | u n k n o w n | u s e | v i e w | v k e r n ) $ / ;
31
30
32
31
const aria_attributes = 'activedescendant atomic autocomplete busy checked colcount colindex colspan controls current describedby description details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowcount rowindex rowspan selected setsize sort valuemax valuemin valuenow valuetext' . split ( ' ' ) ;
33
32
const aria_attribute_set = new Set ( aria_attributes ) ;
34
33
35
- 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 ( ' ' ) ;
34
+ const aria_roles = roles . keys ( ) ;
36
35
const aria_role_set = new Set ( aria_roles ) ;
37
36
const aria_role_abstract_set = new Set ( roles . keys ( ) . filter ( role => roles . get ( role ) . abstract ) ) ;
38
37
@@ -439,6 +438,11 @@ export default class Element extends Node {
439
438
validate_attributes_a11y ( ) {
440
439
const { component, attributes } = this ;
441
440
441
+ const attribute_map = new Map < string , Attribute > ( ) ;
442
+ attributes . forEach ( attribute => (
443
+ attribute_map . set ( attribute . name , attribute )
444
+ ) ) ;
445
+
442
446
attributes . forEach ( attribute => {
443
447
if ( attribute . is_spread ) return ;
444
448
@@ -481,12 +485,11 @@ export default class Element extends Node {
481
485
component . warn ( attribute , compiler_warnings . a11y_misplaced_role ( this . name ) ) ;
482
486
}
483
487
484
- const value = attribute . get_static_value ( ) ;
488
+ const value = attribute . get_static_value ( ) as ARIARoleDefintionKey ;
485
489
486
- if ( value && aria_role_abstract_set . has ( value as ARIARoleDefintionKey ) ) {
490
+ if ( value && aria_role_abstract_set . has ( value ) ) {
487
491
component . warn ( attribute , compiler_warnings . a11y_no_abstract_role ( value ) ) ;
488
- } else if ( value && ! aria_role_set . has ( value as string ) ) {
489
- // @ts -ignore
492
+ } else if ( value && ! aria_role_set . has ( value ) ) {
490
493
const match = fuzzymatch ( value , aria_roles ) ;
491
494
component . warn ( attribute , compiler_warnings . a11y_unknown_role ( value , match ) ) ;
492
495
}
@@ -508,7 +511,7 @@ export default class Element extends Node {
508
511
}
509
512
510
513
// role-has-required-aria-props
511
- const role = roles . get ( value as ARIARoleDefintionKey ) ;
514
+ const role = roles . get ( value ) ;
512
515
if ( role ) {
513
516
const required_role_props = Object . keys ( role . requiredProps ) ;
514
517
const has_missing_props = required_role_props . some ( prop => ! attributes . find ( a => a . name === prop ) ) ;
@@ -517,6 +520,11 @@ export default class Element extends Node {
517
520
component . warn ( attribute , compiler_warnings . a11y_role_has_required_aria_props ( value as string , required_role_props ) ) ;
518
521
}
519
522
}
523
+
524
+ // no-interactive-element-to-noninteractive-role
525
+ if ( is_interactive_element ( this . name , attribute_map ) && ( is_non_interactive_roles ( value ) || is_presentation_role ( value ) ) ) {
526
+ component . warn ( this , compiler_warnings . a11y_no_interactive_element_to_noninteractive_role ( value , this . name ) ) ;
527
+ }
520
528
}
521
529
522
530
// no-access-key
@@ -686,18 +694,6 @@ export default class Element extends Node {
686
694
if ( handlers_map . has ( 'mouseout' ) && ! handlers_map . has ( 'blur' ) ) {
687
695
component . warn ( this , compiler_warnings . a11y_mouse_events_have_key_events ( 'mouseout' , 'blur' ) ) ;
688
696
}
689
-
690
- if ( interactive_elements . has ( this . name ) ) {
691
- if ( attribute_map . has ( 'role' ) ) {
692
- const roleValue = this . attributes . find ( a => a . name === 'role' ) . get_static_value ( ) . toString ( ) as ARIARoleDefintionKey ;
693
- if ( noninteractive_roles . has ( roleValue ) ) {
694
- component . warn ( this , {
695
- code : 'a11y-no-interactive-element-to-noninteractive-role' ,
696
- message : `A11y: <${ this . name } > cannot have role ${ roleValue } `
697
- } ) ;
698
- }
699
- }
700
- }
701
697
}
702
698
703
699
validate_bindings_foreign ( ) {
0 commit comments