diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 93997ae66ece..4c6941c0aaee 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -56,6 +56,11 @@ const a11y_required_content = new Set([ 'h6' ]); +const a11y_no_onchange = new Set([ + 'select', + 'option' +]); + const invisible_elements = new Set(['meta', 'html', 'script', 'style']); const valid_modifiers = new Set([ @@ -424,13 +429,18 @@ export default class Element extends Node { } validate_special_cases() { - const { component,attributes } = this; + const { component, attributes, handlers } = this; const attribute_map = new Map(); + const handlers_map = new Map(); attributes.forEach(attribute => ( attribute_map.set(attribute.name, attribute) )); + handlers.forEach(handler => ( + handlers_map.set(handler.name, handler) + )); + if (this.name === 'a') { const href_attribute = attribute_map.get('href') || attribute_map.get('xlink:href'); const id_attribute = attribute_map.get('id'); @@ -496,6 +506,15 @@ export default class Element extends Node { } } } + + if (a11y_no_onchange.has(this.name)) { + if (handlers_map.has('change') && !handlers_map.has('blur')) { + component.warn(this, { + code: `a11y-no-onchange`, + message: `A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.` + }); + } + } } validate_bindings() { diff --git a/test/validator/samples/a11y-no-onchange/input.svelte b/test/validator/samples/a11y-no-onchange/input.svelte new file mode 100644 index 000000000000..af2041f40679 --- /dev/null +++ b/test/validator/samples/a11y-no-onchange/input.svelte @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/test/validator/samples/a11y-no-onchange/warnings.json b/test/validator/samples/a11y-no-onchange/warnings.json new file mode 100644 index 000000000000..461f546c0bbd --- /dev/null +++ b/test/validator/samples/a11y-no-onchange/warnings.json @@ -0,0 +1,32 @@ +[ + { + "code": "a11y-no-onchange", + "end": { + "character": 88, + "column": 9, + "line": 4 + }, + "message": "A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.", + "pos": 0, + "start": { + "character": 0, + "column": 0, + "line": 1 + } + }, + { + "code": "a11y-no-onchange", + "end": { + "character": 249, + "column": 44, + "line": 10 + }, + "message": "A11y: on:blur must be used instead of on:change, unless absolutely necessary and it causes no negative consequences for keyboard only or screen reader users.", + "pos": 209, + "start": { + "character": 209, + "column": 4, + "line": 10 + } + } +]