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
+ }
+ }
+]