diff --git a/src/compiler/compile/compiler_warnings.ts b/src/compiler/compile/compiler_warnings.ts index 2834847b8b..f194090870 100644 --- a/src/compiler/compile/compiler_warnings.ts +++ b/src/compiler/compile/compiler_warnings.ts @@ -175,6 +175,10 @@ export default { code: 'a11y-mouse-events-have-key-events', message: `A11y: on:${event} must be accompanied by on:${accompanied_by}` }), + a11y_click_events_have_key_events: () => ({ + code: 'a11y-click-events-have-key-events', + message: 'A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.' + }), a11y_missing_content: (name: string) => ({ code: 'a11y-missing-content', message: `A11y: <${name}> element should have child content` diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index abe48e2f6d..bab4807582 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -115,6 +115,23 @@ const a11y_implicit_semantics = new Map([ ['ul', 'list'] ]); +const a11y_interactive = new Set([ + 'a', + 'button', + 'select' +]); + +const input_type_interactive = new Set([ + 'button', + 'checkbox', + 'color', + 'file', + 'image', + 'radio', + 'reset', + 'submit' +]); + const invisible_elements = new Set(['meta', 'html', 'script', 'style']); const valid_modifiers = new Set([ @@ -557,20 +574,12 @@ export default class Element extends Node { // click-events-have-key-events if (handlers_map.has('click')) { - - const a11y_interactive = new Set([ - 'a', - 'button', - 'select' - ]); - if (a11y_interactive.has(this.name)) { return; } if (this.name === 'input') { const input_type = attribute_map.get('type'); - const input_type_interactive = new Set(['button', 'checkbox', 'color', 'file', 'image', 'radio', 'reset', 'submit']); if (input_type && input_type_interactive.has(input_type.get_static_value())) { return; @@ -606,16 +615,16 @@ export default class Element extends Node { return; } - const hasKeyEvent = + const has_key_event = handlers_map.has('keydown') || handlers_map.has('keyup') || handlers_map.has('keypress'); - if (!hasKeyEvent) { - component.warn(this, { - code: `a11y-click-events-have-key-events`, - message: `A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.` - }); + if (!has_key_event) { + component.warn( + this, + compiler_warnings.a11y_click_events_have_key_events() + ); } } diff --git a/test/validator/samples/a11y-click-events-have-key-events/warnings.json b/test/validator/samples/a11y-click-events-have-key-events/warnings.json index c0da1e6fcf..109d58e97f 100644 --- a/test/validator/samples/a11y-click-events-have-key-events/warnings.json +++ b/test/validator/samples/a11y-click-events-have-key-events/warnings.json @@ -1,7 +1,7 @@ [ { "code": "a11y-click-events-have-key-events", - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "end": { "character": 102, "column": 23, @@ -21,7 +21,7 @@ "column": 43, "line": 9 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 103, "start": { "character": 103, @@ -36,7 +36,7 @@ "column": 40, "line": 10 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 147, "start": { "character": 147, @@ -51,7 +51,7 @@ "column": 27, "line": 12 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 189, "start": { "character": 189, @@ -66,7 +66,7 @@ "column": 24, "line": 13 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 217, "start": { "character": 217, @@ -81,7 +81,7 @@ "column": 27, "line": 14 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 242, "start": { "character": 242, @@ -96,7 +96,7 @@ "column": 26, "line": 15 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 270, "start": { "character": 270, @@ -111,7 +111,7 @@ "column": 26, "line": 16 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 297, "start": { "character": 297, @@ -126,7 +126,7 @@ "column": 37, "line": 18 }, - "message": "A11y: visible, non-interactive elements with on:click event must be accompanied by a on:keydown, on:keyup or on:keypress event.", + "message": "A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.", "pos": 325, "start": { "character": 325,