From e4bb4d682007658448cad55bae683d2b05e5f1ad Mon Sep 17 00:00:00 2001 From: Melonai Date: Sun, 3 Jan 2021 18:47:27 +0100 Subject: [PATCH 1/6] Check required props for ARIA roles --- src/compiler/compile/nodes/Element.ts | 33 +++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 735562d6274..f9dad93a75c 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -45,6 +45,20 @@ const a11y_required_attributes = { object: ['title', 'aria-label', 'aria-labelledby'] }; +const a11y_required_role_props = { + checkbox: ['aria-checked'], + combobox: ['aria-controls', 'aria-expanded'], + heading: ['aria-level'], + menuitemcheckbox: ['aria-checked'], + menuitemradio: ['aria-checked'], + meter: ['aria-valuemax', 'aria-valuemin', 'aria-valuenow'], + option: ['aria-selected'], + radio: ['aria-checked'], + scrollbar: ['aria-controls', 'aria-valuenow'], + slider: ['aria-valuenow'], + switch: ['aria-checked'] +}; + const a11y_distracting_elements = new Set([ 'blink', 'marquee' @@ -407,9 +421,9 @@ export default class Element extends Node { } validate_attributes_a11y() { - const { component } = this; + const { component, attributes } = this; - this.attributes.forEach(attribute => { + attributes.forEach(attribute => { if (attribute.is_spread) return; const name = attribute.name.toLowerCase(); @@ -462,6 +476,21 @@ export default class Element extends Node { component.warn(attribute, compiler_warnings.a11y_no_redundant_roles(value)); } } + + // @ts-ignore + const required_role_props = a11y_required_role_props[value]; + + // role-has-required-aria-props + if (required_role_props) { + const has_missing_props = required_role_props.some(prop => !attributes.find(a => a.name === prop)); + + if (has_missing_props) { + component.warn(attribute, { + code: 'a11y-role-has-required-aria-props', + message: `A11y: Elements with the ARIA role "${value}" must have the following attributes defined: ${String(required_role_props)}` + }); + } + } } // no-access-key From a2be133b7805d88c4ab84b39ed1205b8386cb129 Mon Sep 17 00:00:00 2001 From: Melonai Date: Sun, 3 Jan 2021 18:49:13 +0100 Subject: [PATCH 2/6] Test required ARIA props check --- .../input.svelte | 7 +++ .../warnings.json | 47 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 test/validator/samples/a11y-role-has-required-aria-props/input.svelte create mode 100644 test/validator/samples/a11y-role-has-required-aria-props/warnings.json diff --git a/test/validator/samples/a11y-role-has-required-aria-props/input.svelte b/test/validator/samples/a11y-role-has-required-aria-props/input.svelte new file mode 100644 index 00000000000..b3d2af589b4 --- /dev/null +++ b/test/validator/samples/a11y-role-has-required-aria-props/input.svelte @@ -0,0 +1,7 @@ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/test/validator/samples/a11y-role-has-required-aria-props/warnings.json b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json new file mode 100644 index 00000000000..4d898ebb804 --- /dev/null +++ b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json @@ -0,0 +1,47 @@ +[ + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: aria-level", + "start": { + "line": 1, + "column": 5, + "character": 5 + }, + "end": { + "line": 1, + "column": 19, + "character": 19 + }, + "pos": 5 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: aria-checked", + "start": { + "line": 2, + "column": 6, + "character": 33 + }, + "end": { + "line": 2, + "column": 21, + "character": 48 + }, + "pos": 33 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: aria-valuemax,aria-valuemin,aria-valuenow", + "start": { + "line": 3, + "column": 5, + "character": 62 + }, + "end": { + "line": 3, + "column": 17, + "character": 74 + }, + "pos": 62 + } +] From a85e5d3947fddadc99a0530e3e11ffdedfe2b72d Mon Sep 17 00:00:00 2001 From: Melonai Date: Mon, 4 Jan 2021 00:16:18 +0100 Subject: [PATCH 3/6] Properly indent with tabs in test --- .../warnings.json | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/test/validator/samples/a11y-role-has-required-aria-props/warnings.json b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json index 4d898ebb804..c0f5a3b02d0 100644 --- a/test/validator/samples/a11y-role-has-required-aria-props/warnings.json +++ b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json @@ -13,35 +13,35 @@ "character": 19 }, "pos": 5 - }, - { - "code": "a11y-role-has-required-aria-props", - "message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: aria-checked", - "start": { - "line": 2, - "column": 6, - "character": 33 - }, - "end": { - "line": 2, - "column": 21, - "character": 48 - }, - "pos": 33 - }, - { - "code": "a11y-role-has-required-aria-props", - "message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: aria-valuemax,aria-valuemin,aria-valuenow", - "start": { - "line": 3, - "column": 5, - "character": 62 - }, - "end": { - "line": 3, - "column": 17, - "character": 74 - }, - "pos": 62 - } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: aria-checked", + "start": { + "line": 2, + "column": 6, + "character": 33 + }, + "end": { + "line": 2, + "column": 21, + "character": 48 + }, + "pos": 33 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: aria-valuemax,aria-valuemin,aria-valuenow", + "start": { + "line": 3, + "column": 5, + "character": 62 + }, + "end": { + "line": 3, + "column": 17, + "character": 74 + }, + "pos": 62 + } ] From 622bfc108b469b143ad425b0ccd9080fae3f1107 Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Sun, 10 Jul 2022 23:46:53 +0800 Subject: [PATCH 4/6] swtich to use aria-query --- package-lock.json | 29 +++++++++++++++++++ package.json | 2 ++ src/compiler/compile/compiler_warnings.ts | 4 +++ src/compiler/compile/nodes/Element.ts | 27 ++++------------- .../input.svelte | 4 ++- .../warnings.json | 21 ++++++++++++-- 6 files changed, 61 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 38abdfc3306..ab4b20ed594 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,12 +18,14 @@ "@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-virtual": "^2.0.0", "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.8.0", + "@types/aria-query": "^5.0.0", "@types/mocha": "^7.0.0", "@types/node": "^8.10.53", "@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/parser": "^5.22.0", "acorn": "^8.4.1", "agadoo": "^1.1.0", + "aria-query": "^5.0.0", "code-red": "^0.2.5", "css-tree": "^1.1.2", "eslint": "^8.0.0", @@ -285,6 +287,12 @@ "resolved": "git+ssh://git@github.com/sveltejs/eslint-config.git#31fd4faeea88990069502460b023698b1c9c2d13", "dev": true }, + "node_modules/@types/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-P+dkdFu0n08PDIvw+9nT9ByQnd+Udc8DaWPb9HKfaPwCvWvQpC5XaMRx2xLWECm9x1VKNps6vEAlirjA6+uNrQ==", + "dev": true + }, "node_modules/@types/estree": { "version": "0.0.50", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", @@ -698,6 +706,15 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -4927,6 +4944,12 @@ "dev": true, "from": "@sveltejs/eslint-config@github:sveltejs/eslint-config#v5.8.0" }, + "@types/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-P+dkdFu0n08PDIvw+9nT9ByQnd+Udc8DaWPb9HKfaPwCvWvQpC5XaMRx2xLWECm9x1VKNps6vEAlirjA6+uNrQ==", + "dev": true + }, "@types/estree": { "version": "0.0.50", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz", @@ -5208,6 +5231,12 @@ "sprintf-js": "~1.0.2" } }, + "aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", diff --git a/package.json b/package.json index de712b9bab9..ade713f4e3f 100644 --- a/package.json +++ b/package.json @@ -124,12 +124,14 @@ "@rollup/plugin-typescript": "^2.0.1", "@rollup/plugin-virtual": "^2.0.0", "@sveltejs/eslint-config": "github:sveltejs/eslint-config#v5.8.0", + "@types/aria-query": "^5.0.0", "@types/mocha": "^7.0.0", "@types/node": "^8.10.53", "@typescript-eslint/eslint-plugin": "^5.22.0", "@typescript-eslint/parser": "^5.22.0", "acorn": "^8.4.1", "agadoo": "^1.1.0", + "aria-query": "^5.0.0", "code-red": "^0.2.5", "css-tree": "^1.1.2", "eslint": "^8.0.0", diff --git a/src/compiler/compile/compiler_warnings.ts b/src/compiler/compile/compiler_warnings.ts index 86ec98cb8b1..833722c3b95 100644 --- a/src/compiler/compile/compiler_warnings.ts +++ b/src/compiler/compile/compiler_warnings.ts @@ -80,6 +80,10 @@ export default { code: 'a11y-no-redundant-roles', message: `A11y: Redundant role '${role}'` }), + a11y_role_has_required_aria_props: (role: string, props: string[]) => ({ + code: 'a11y-role-has-required-aria-props', + message: `A11y: Elements with the ARIA role "${role}" must have the following attributes defined: ${props.map(name => `"${name}"`).join(', ')}` + }), a11y_accesskey: { code: 'a11y-accesskey', message: 'A11y: Avoid using accesskey' diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index f9dad93a75c..35131cefcfd 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -23,6 +23,7 @@ import { string_literal } from '../utils/stringify'; import { Literal } from 'estree'; import compiler_warnings from '../compiler_warnings'; import compiler_errors from '../compiler_errors'; +import { ARIARoleDefintionKey, roles } from 'aria-query'; const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/; @@ -45,20 +46,6 @@ const a11y_required_attributes = { object: ['title', 'aria-label', 'aria-labelledby'] }; -const a11y_required_role_props = { - checkbox: ['aria-checked'], - combobox: ['aria-controls', 'aria-expanded'], - heading: ['aria-level'], - menuitemcheckbox: ['aria-checked'], - menuitemradio: ['aria-checked'], - meter: ['aria-valuemax', 'aria-valuemin', 'aria-valuenow'], - option: ['aria-selected'], - radio: ['aria-checked'], - scrollbar: ['aria-controls', 'aria-valuenow'], - slider: ['aria-valuenow'], - switch: ['aria-checked'] -}; - const a11y_distracting_elements = new Set([ 'blink', 'marquee' @@ -477,18 +464,14 @@ export default class Element extends Node { } } - // @ts-ignore - const required_role_props = a11y_required_role_props[value]; - // role-has-required-aria-props - if (required_role_props) { + const role = roles.get(value as ARIARoleDefintionKey); + if (role) { + const required_role_props = Object.keys(role.requiredProps); const has_missing_props = required_role_props.some(prop => !attributes.find(a => a.name === prop)); if (has_missing_props) { - component.warn(attribute, { - code: 'a11y-role-has-required-aria-props', - message: `A11y: Elements with the ARIA role "${value}" must have the following attributes defined: ${String(required_role_props)}` - }); + component.warn(attribute, compiler_warnings.a11y_role_has_required_aria_props(value as string, required_role_props)); } } } diff --git a/test/validator/samples/a11y-role-has-required-aria-props/input.svelte b/test/validator/samples/a11y-role-has-required-aria-props/input.svelte index b3d2af589b4..8e88b089080 100644 --- a/test/validator/samples/a11y-role-has-required-aria-props/input.svelte +++ b/test/validator/samples/a11y-role-has-required-aria-props/input.svelte @@ -1,7 +1,9 @@
+
-
\ No newline at end of file +
+
diff --git a/test/validator/samples/a11y-role-has-required-aria-props/warnings.json b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json index c0f5a3b02d0..4de7c840016 100644 --- a/test/validator/samples/a11y-role-has-required-aria-props/warnings.json +++ b/test/validator/samples/a11y-role-has-required-aria-props/warnings.json @@ -1,7 +1,7 @@ [ { "code": "a11y-role-has-required-aria-props", - "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: aria-level", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", "start": { "line": 1, "column": 5, @@ -16,7 +16,7 @@ }, { "code": "a11y-role-has-required-aria-props", - "message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: aria-checked", + "message": "A11y: Elements with the ARIA role \"checkbox\" must have the following attributes defined: \"aria-checked\"", "start": { "line": 2, "column": 6, @@ -31,7 +31,7 @@ }, { "code": "a11y-role-has-required-aria-props", - "message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: aria-valuemax,aria-valuemin,aria-valuenow", + "message": "A11y: Elements with the ARIA role \"meter\" must have the following attributes defined: \"aria-valuenow\"", "start": { "line": 3, "column": 5, @@ -43,5 +43,20 @@ "character": 74 }, "pos": 62 + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"scrollbar\" must have the following attributes defined: \"aria-controls\", \"aria-valuenow\"", + "start": { + "character": 87, + "column": 5, + "line": 4 + }, + "end": { + "character": 103, + "column": 21, + "line": 4 + }, + "pos": 87 } ] From 735811918959c71ca5890d85b855e3ab980d9355 Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Mon, 11 Jul 2022 00:14:30 +0800 Subject: [PATCH 5/6] fix validation test --- .../a11y-no-redundant-roles/warnings.json | 1367 +++++++++-------- 1 file changed, 736 insertions(+), 631 deletions(-) diff --git a/test/validator/samples/a11y-no-redundant-roles/warnings.json b/test/validator/samples/a11y-no-redundant-roles/warnings.json index 8aa3520b323..0947a467af0 100644 --- a/test/validator/samples/a11y-no-redundant-roles/warnings.json +++ b/test/validator/samples/a11y-no-redundant-roles/warnings.json @@ -1,632 +1,737 @@ [ - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 23, - "column": 23, - "line": 1 - }, - "message": "A11y: Redundant role 'link'", - "pos": 12, - "start": { - "character": 12, - "column": 12, - "line": 1 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 58, - "column": 23, - "line": 2 - }, - "message": "A11y: Redundant role 'article'", - "pos": 44, - "start": { - "character": 44, - "column": 9, - "line": 2 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 89, - "column": 27, - "line": 3 - }, - "message": "A11y: Redundant role 'complementary'", - "pos": 69, - "start": { - "character": 69, - "column": 7, - "line": 3 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 114, - "column": 21, - "line": 4 - }, - "message": "A11y: Redundant role 'document'", - "pos": 99, - "start": { - "character": 99, - "column": 6, - "line": 4 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 139, - "column": 21, - "line": 5 - }, - "message": "A11y: Redundant role 'button'", - "pos": 126, - "start": { - "character": 126, - "column": 8, - "line": 5 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 167, - "column": 24, - "line": 6 - }, - "message": "A11y: Redundant role 'listbox'", - "pos": 153, - "start": { - "character": 153, - "column": 10, - "line": 6 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 192, - "column": 21, - "line": 7 - }, - "message": "A11y: Redundant role 'definition'", - "pos": 175, - "start": { - "character": 175, - "column": 4, - "line": 7 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 212, - "column": 16, - "line": 8 - }, - "message": "A11y: Redundant role 'term'", - "pos": 201, - "start": { - "character": 201, - "column": 5, - "line": 8 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 237, - "column": 21, - "line": 9 - }, - "message": "A11y: Redundant role 'group'", - "pos": 225, - "start": { - "character": 225, - "column": 9, - "line": 9 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 262, - "column": 21, - "line": 10 - }, - "message": "A11y: Redundant role 'dialog'", - "pos": 249, - "start": { - "character": 249, - "column": 8, - "line": 10 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 281, - "column": 15, - "line": 11 - }, - "message": "A11y: Redundant role 'term'", - "pos": 270, - "start": { - "character": 270, - "column": 4, - "line": 11 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 307, - "column": 22, - "line": 12 - }, - "message": "A11y: Redundant role 'group'", - "pos": 295, - "start": { - "character": 295, - "column": 10, - "line": 12 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 332, - "column": 21, - "line": 13 - }, - "message": "A11y: Redundant role 'figure'", - "pos": 319, - "start": { - "character": 319, - "column": 8, - "line": 13 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 353, - "column": 17, - "line": 14 - }, - "message": "A11y: Redundant role 'form'", - "pos": 342, - "start": { - "character": 342, - "column": 6, - "line": 14 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 383, - "column": 18, - "line": 15 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 369, - "start": { - "character": 369, - "column": 4, - "line": 15 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 415, - "column": 18, - "line": 16 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 401, - "start": { - "character": 401, - "column": 4, - "line": 16 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 447, - "column": 18, - "line": 17 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 433, - "start": { - "character": 433, - "column": 4, - "line": 17 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 479, - "column": 18, - "line": 18 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 465, - "start": { - "character": 465, - "column": 4, - "line": 18 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 511, - "column": 18, - "line": 19 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 497, - "start": { - "character": 497, - "column": 4, - "line": 19 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 543, - "column": 18, - "line": 20 - }, - "message": "A11y: Redundant role 'heading'", - "pos": 529, - "start": { - "character": 529, - "column": 4, - "line": 20 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 577, - "column": 20, - "line": 21 - }, - "message": "A11y: Redundant role 'separator'", - "pos": 561, - "start": { - "character": 561, - "column": 4, - "line": 21 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 600, - "column": 19, - "line": 22 - }, - "message": "A11y: Redundant role 'listitem'", - "pos": 585, - "start": { - "character": 585, - "column": 4, - "line": 22 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 621, - "column": 17, - "line": 23 - }, - "message": "A11y: Redundant role 'link'", - "pos": 610, - "start": { - "character": 610, - "column": 6, - "line": 23 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 642, - "column": 17, - "line": 24 - }, - "message": "A11y: Redundant role 'main'", - "pos": 631, - "start": { - "character": 631, - "column": 6, - "line": 24 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 668, - "column": 17, - "line": 25 - }, - "message": "A11y: Redundant role 'list'", - "pos": 657, - "start": { - "character": 657, - "column": 6, - "line": 25 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 694, - "column": 22, - "line": 26 - }, - "message": "A11y: Redundant role 'navigation'", - "pos": 677, - "start": { - "character": 677, - "column": 5, - "line": 26 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 713, - "column": 15, - "line": 27 - }, - "message": "A11y: Redundant role 'list'", - "pos": 702, - "start": { - "character": 702, - "column": 4, - "line": 27 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 739, - "column": 22, - "line": 28 - }, - "message": "A11y: Redundant role 'group'", - "pos": 727, - "start": { - "character": 727, - "column": 10, - "line": 28 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 764, - "column": 21, - "line": 29 - }, - "message": "A11y: Redundant role 'option'", - "pos": 751, - "start": { - "character": 751, - "column": 8, - "line": 29 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 789, - "column": 21, - "line": 30 - }, - "message": "A11y: Redundant role 'status'", - "pos": 776, - "start": { - "character": 776, - "column": 8, - "line": 30 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 821, - "column": 28, - "line": 31 - }, - "message": "A11y: Redundant role 'progressbar'", - "pos": 803, - "start": { - "character": 803, - "column": 10, - "line": 31 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 847, - "column": 22, - "line": 32 - }, - "message": "A11y: Redundant role 'region'", - "pos": 834, - "start": { - "character": 834, - "column": 9, - "line": 32 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 873, - "column": 22, - "line": 33 - }, - "message": "A11y: Redundant role 'button'", - "pos": 860, - "start": { - "character": 860, - "column": 9, - "line": 33 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 896, - "column": 19, - "line": 34 - }, - "message": "A11y: Redundant role 'table'", - "pos": 884, - "start": { - "character": 884, - "column": 7, - "line": 34 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 922, - "column": 22, - "line": 35 - }, - "message": "A11y: Redundant role 'rowgroup'", - "pos": 907, - "start": { - "character": 907, - "column": 7, - "line": 35 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 950, - "column": 24, - "line": 36 - }, - "message": "A11y: Redundant role 'textbox'", - "pos": 936, - "start": { - "character": 936, - "column": 10, - "line": 36 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 976, - "column": 22, - "line": 37 - }, - "message": "A11y: Redundant role 'rowgroup'", - "pos": 961, - "start": { - "character": 961, - "column": 7, - "line": 37 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1002, - "column": 22, - "line": 38 - }, - "message": "A11y: Redundant role 'rowgroup'", - "pos": 987, - "start": { - "character": 987, - "column": 7, - "line": 38 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1020, - "column": 14, - "line": 39 - }, - "message": "A11y: Redundant role 'row'", - "pos": 1010, - "start": { - "character": 1010, - "column": 4, - "line": 39 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1039, - "column": 15, - "line": 40 - }, - "message": "A11y: Redundant role 'list'", - "pos": 1028, - "start": { - "character": 1028, - "column": 4, - "line": 40 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1125, - "column": 21, - "line": 43 - }, - "message": "A11y: Redundant role 'banner'", - "pos": 1112, - "start": { - "character": 1112, - "column": 8, - "line": 43 - } - }, - { - "code": "a11y-no-redundant-roles", - "end": { - "character": 1162, - "column": 26, - "line": 44 - }, - "message": "A11y: Redundant role 'contentinfo'", - "pos": 1144, - "start": { - "character": 1144, - "column": 8, - "line": 44 - } - } -] \ No newline at end of file + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 23, + "column": 23, + "line": 1 + }, + "message": "A11y: Redundant role 'link'", + "pos": 12, + "start": { + "character": 12, + "column": 12, + "line": 1 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 58, + "column": 23, + "line": 2 + }, + "message": "A11y: Redundant role 'article'", + "pos": 44, + "start": { + "character": 44, + "column": 9, + "line": 2 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 89, + "column": 27, + "line": 3 + }, + "message": "A11y: Redundant role 'complementary'", + "pos": 69, + "start": { + "character": 69, + "column": 7, + "line": 3 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 114, + "column": 21, + "line": 4 + }, + "message": "A11y: Redundant role 'document'", + "pos": 99, + "start": { + "character": 99, + "column": 6, + "line": 4 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 139, + "column": 21, + "line": 5 + }, + "message": "A11y: Redundant role 'button'", + "pos": 126, + "start": { + "character": 126, + "column": 8, + "line": 5 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 167, + "column": 24, + "line": 6 + }, + "message": "A11y: Redundant role 'listbox'", + "pos": 153, + "start": { + "character": 153, + "column": 10, + "line": 6 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 192, + "column": 21, + "line": 7 + }, + "message": "A11y: Redundant role 'definition'", + "pos": 175, + "start": { + "character": 175, + "column": 4, + "line": 7 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 212, + "column": 16, + "line": 8 + }, + "message": "A11y: Redundant role 'term'", + "pos": 201, + "start": { + "character": 201, + "column": 5, + "line": 8 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 237, + "column": 21, + "line": 9 + }, + "message": "A11y: Redundant role 'group'", + "pos": 225, + "start": { + "character": 225, + "column": 9, + "line": 9 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 262, + "column": 21, + "line": 10 + }, + "message": "A11y: Redundant role 'dialog'", + "pos": 249, + "start": { + "character": 249, + "column": 8, + "line": 10 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 281, + "column": 15, + "line": 11 + }, + "message": "A11y: Redundant role 'term'", + "pos": 270, + "start": { + "character": 270, + "column": 4, + "line": 11 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 307, + "column": 22, + "line": 12 + }, + "message": "A11y: Redundant role 'group'", + "pos": 295, + "start": { + "character": 295, + "column": 10, + "line": 12 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 332, + "column": 21, + "line": 13 + }, + "message": "A11y: Redundant role 'figure'", + "pos": 319, + "start": { + "character": 319, + "column": 8, + "line": 13 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 353, + "column": 17, + "line": 14 + }, + "message": "A11y: Redundant role 'form'", + "pos": 342, + "start": { + "character": 342, + "column": 6, + "line": 14 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 383, + "column": 18, + "line": 15 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 369, + "start": { + "character": 369, + "column": 4, + "line": 15 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "end": { + "character": 383, + "column": 18, + "line": 15 + }, + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 369, + "start": { + "character": 369, + "column": 4, + "line": 15 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 415, + "column": 18, + "line": 16 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 401, + "start": { + "character": 401, + "column": 4, + "line": 16 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 401, + "start": { + "character": 401, + "column": 4, + "line": 16 + }, + "end": { + "character": 415, + "column": 18, + "line": 16 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 447, + "column": 18, + "line": 17 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 433, + "start": { + "character": 433, + "column": 4, + "line": 17 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "end": { + "character": 447, + "column": 18, + "line": 17 + }, + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 433, + "start": { + "character": 433, + "column": 4, + "line": 17 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 479, + "column": 18, + "line": 18 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 465, + "start": { + "character": 465, + "column": 4, + "line": 18 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 465, + "start": { + "character": 465, + "column": 4, + "line": 18 + }, + "end": { + "character": 479, + "column": 18, + "line": 18 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 511, + "column": 18, + "line": 19 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 497, + "start": { + "character": 497, + "column": 4, + "line": 19 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 497, + "start": { + "character": 497, + "column": 4, + "line": 19 + }, + "end": { + "character": 511, + "column": 18, + "line": 19 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 543, + "column": 18, + "line": 20 + }, + "message": "A11y: Redundant role 'heading'", + "pos": 529, + "start": { + "character": 529, + "column": 4, + "line": 20 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"heading\" must have the following attributes defined: \"aria-level\"", + "pos": 529, + "start": { + "character": 529, + "column": 4, + "line": 20 + }, + "end": { + "character": 543, + "column": 18, + "line": 20 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 577, + "column": 20, + "line": 21 + }, + "message": "A11y: Redundant role 'separator'", + "pos": 561, + "start": { + "character": 561, + "column": 4, + "line": 21 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 600, + "column": 19, + "line": 22 + }, + "message": "A11y: Redundant role 'listitem'", + "pos": 585, + "start": { + "character": 585, + "column": 4, + "line": 22 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 621, + "column": 17, + "line": 23 + }, + "message": "A11y: Redundant role 'link'", + "pos": 610, + "start": { + "character": 610, + "column": 6, + "line": 23 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 642, + "column": 17, + "line": 24 + }, + "message": "A11y: Redundant role 'main'", + "pos": 631, + "start": { + "character": 631, + "column": 6, + "line": 24 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 668, + "column": 17, + "line": 25 + }, + "message": "A11y: Redundant role 'list'", + "pos": 657, + "start": { + "character": 657, + "column": 6, + "line": 25 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 694, + "column": 22, + "line": 26 + }, + "message": "A11y: Redundant role 'navigation'", + "pos": 677, + "start": { + "character": 677, + "column": 5, + "line": 26 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 713, + "column": 15, + "line": 27 + }, + "message": "A11y: Redundant role 'list'", + "pos": 702, + "start": { + "character": 702, + "column": 4, + "line": 27 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 739, + "column": 22, + "line": 28 + }, + "message": "A11y: Redundant role 'group'", + "pos": 727, + "start": { + "character": 727, + "column": 10, + "line": 28 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 764, + "column": 21, + "line": 29 + }, + "message": "A11y: Redundant role 'option'", + "pos": 751, + "start": { + "character": 751, + "column": 8, + "line": 29 + } + }, + { + "code": "a11y-role-has-required-aria-props", + "message": "A11y: Elements with the ARIA role \"option\" must have the following attributes defined: \"aria-selected\"", + "pos": 751, + "start": { + "character": 751, + "column": 8, + "line": 29 + }, + "end": { + "character": 764, + "column": 21, + "line": 29 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 789, + "column": 21, + "line": 30 + }, + "message": "A11y: Redundant role 'status'", + "pos": 776, + "start": { + "character": 776, + "column": 8, + "line": 30 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 821, + "column": 28, + "line": 31 + }, + "message": "A11y: Redundant role 'progressbar'", + "pos": 803, + "start": { + "character": 803, + "column": 10, + "line": 31 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 847, + "column": 22, + "line": 32 + }, + "message": "A11y: Redundant role 'region'", + "pos": 834, + "start": { + "character": 834, + "column": 9, + "line": 32 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 873, + "column": 22, + "line": 33 + }, + "message": "A11y: Redundant role 'button'", + "pos": 860, + "start": { + "character": 860, + "column": 9, + "line": 33 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 896, + "column": 19, + "line": 34 + }, + "message": "A11y: Redundant role 'table'", + "pos": 884, + "start": { + "character": 884, + "column": 7, + "line": 34 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 922, + "column": 22, + "line": 35 + }, + "message": "A11y: Redundant role 'rowgroup'", + "pos": 907, + "start": { + "character": 907, + "column": 7, + "line": 35 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 950, + "column": 24, + "line": 36 + }, + "message": "A11y: Redundant role 'textbox'", + "pos": 936, + "start": { + "character": 936, + "column": 10, + "line": 36 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 976, + "column": 22, + "line": 37 + }, + "message": "A11y: Redundant role 'rowgroup'", + "pos": 961, + "start": { + "character": 961, + "column": 7, + "line": 37 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1002, + "column": 22, + "line": 38 + }, + "message": "A11y: Redundant role 'rowgroup'", + "pos": 987, + "start": { + "character": 987, + "column": 7, + "line": 38 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1020, + "column": 14, + "line": 39 + }, + "message": "A11y: Redundant role 'row'", + "pos": 1010, + "start": { + "character": 1010, + "column": 4, + "line": 39 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1039, + "column": 15, + "line": 40 + }, + "message": "A11y: Redundant role 'list'", + "pos": 1028, + "start": { + "character": 1028, + "column": 4, + "line": 40 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1125, + "column": 21, + "line": 43 + }, + "message": "A11y: Redundant role 'banner'", + "pos": 1112, + "start": { + "character": 1112, + "column": 8, + "line": 43 + } + }, + { + "code": "a11y-no-redundant-roles", + "end": { + "character": 1162, + "column": 26, + "line": 44 + }, + "message": "A11y: Redundant role 'contentinfo'", + "pos": 1144, + "start": { + "character": 1144, + "column": 8, + "line": 44 + } + } +] From 6276186d8d642f2d6408373bd11d44482b752247 Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Mon, 11 Jul 2022 02:10:59 +0800 Subject: [PATCH 6/6] update docs --- site/content/docs/05-accessibility-warnings.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/site/content/docs/05-accessibility-warnings.md b/site/content/docs/05-accessibility-warnings.md index b39b06f9ffb..9d0835b4432 100644 --- a/site/content/docs/05-accessibility-warnings.md +++ b/site/content/docs/05-accessibility-warnings.md @@ -54,6 +54,17 @@ The following elements are visually distracting: `` and ``. --- +### `role-has-required-aria-props` + +Elements with ARIA roles must have all required attributes for that role. + +```sv + + +``` + +--- + ### `a11y-hidden` Certain DOM elements are useful for screen reader navigation and should not be hidden.