From 6c3aea607c8e92f65943db4a009b4b07e6c8ad45 Mon Sep 17 00:00:00 2001 From: Anthony Le Goas Date: Wed, 3 Feb 2021 13:55:01 +0100 Subject: [PATCH] check noninteractive roles on interactive elements --- src/compiler/compile/nodes/Element.ts | 20 + .../input.svelte | 54 ++ .../warnings.json | 602 ++++++++++++++++++ 3 files changed, 676 insertions(+) create mode 100644 test/validator/samples/a11y-no-interactive-element-to-noninteractive-role/input.svelte create mode 100644 test/validator/samples/a11y-no-interactive-element-to-noninteractive-role/warnings.json diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 07f17390182e..5b474f4fb9dd 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -98,6 +98,14 @@ const react_attributes = new Map([ ['htmlFor', 'for'] ]); +const interactive_elements = new Set([ + 'a', 'button', 'input', 'select', 'textarea' +]); + +const noninteractive_roles = new Set([ + 'article', 'banner', 'complementary', 'img', 'listitem', 'main', 'region', 'tooltip' +]); + function get_namespace(parent: Element, element: Element, explicit_namespace: string) { const parent_element = parent.find_nearest(/^Element/); @@ -596,6 +604,18 @@ export default class Element extends Node { }); } } + + if (interactive_elements.has(this.name)) { + if (attribute_map.has('role')) { + const roleValue = this.attributes.find(a => a.name === 'role').get_static_value().toString(); + if (noninteractive_roles.has(roleValue)) { + component.warn(this, { + code: 'a11y-no-interactive-element-to-noninteractive-role', + message: `A11y: <${this.name}> cannot have role ${roleValue}` + }); + } + } + } } validate_bindings_foreign() { diff --git a/test/validator/samples/a11y-no-interactive-element-to-noninteractive-role/input.svelte b/test/validator/samples/a11y-no-interactive-element-to-noninteractive-role/input.svelte new file mode 100644 index 000000000000..ad12bcfd069d --- /dev/null +++ b/test/validator/samples/a11y-no-interactive-element-to-noninteractive-role/input.svelte @@ -0,0 +1,54 @@ + +link +link +link +link +link +link +link +link +link + + + + + + + + + + + + + + + + + + + + + + + + + + + + +