diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 1d844bfb36..9e7759a5f9 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -82,6 +82,7 @@ Rules that do not necessarily conform to WCAG success criterion but are industry | [accesskeys](https://dequeuniversity.com/rules/axe/4.1/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.1/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.1/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | +| [aria-text](https://dequeuniversity.com/rules/axe/4.1/aria-text?application=RuleDescription) | Ensures "role=text" is used correctly | Serious | cat.aria, best-practice | failure, needs review | | [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.1/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | [empty-heading](https://dequeuniversity.com/rules/axe/4.1/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | [frame-tested](https://dequeuniversity.com/rules/axe/4.1/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | diff --git a/lib/rules/aria-text.json b/lib/rules/aria-text.json new file mode 100644 index 0000000000..aa284a5867 --- /dev/null +++ b/lib/rules/aria-text.json @@ -0,0 +1,12 @@ +{ + "id": "aria-text", + "selector": "[role=text]", + "tags": ["cat.aria", "best-practice"], + "metadata": { + "description": "Ensures \"role=text\" is used on elements with no focusable descendants", + "help": "\"role=text\" should have no focusable descendants" + }, + "all": [], + "any": ["no-focusable-content"], + "none": [] +} diff --git a/lib/standards/aria-roles.js b/lib/standards/aria-roles.js index 6b1ac245d8..aa572103b0 100644 --- a/lib/standards/aria-roles.js +++ b/lib/standards/aria-roles.js @@ -719,6 +719,11 @@ const ariaRoles = { // Note: spec difference nameFromContent: true }, + text: { + type: 'structure', + superclassRole: ['section'], + nameFromContent: true + }, textbox: { type: 'widget', allowedAttrs: [ diff --git a/test/commons/standards/get-aria-roles-by-type.js b/test/commons/standards/get-aria-roles-by-type.js index 012a319c6a..c7da0b3515 100644 --- a/test/commons/standards/get-aria-roles-by-type.js +++ b/test/commons/standards/get-aria-roles-by-type.js @@ -47,6 +47,7 @@ describe('standards.getAriaRolesByType', function() { 'superscript', 'table', 'term', + 'text', 'time', 'toolbar', 'tooltip' diff --git a/test/commons/standards/get-aria-roles-supporting-name-from-content.js b/test/commons/standards/get-aria-roles-supporting-name-from-content.js index 525e279aee..4e1af1ee4f 100644 --- a/test/commons/standards/get-aria-roles-supporting-name-from-content.js +++ b/test/commons/standards/get-aria-roles-supporting-name-from-content.js @@ -43,6 +43,7 @@ describe('standards.getAriaRolesSupportingNameFromContent', function() { 'tab', 'table', 'term', + 'text', 'tooltip', 'treeitem', 'doc-backlink', diff --git a/test/integration/rules/aria-allowed-role/aria-allowed-role.html b/test/integration/rules/aria-allowed-role/aria-allowed-role.html index 63c319d006..5185019996 100644 --- a/test/integration/rules/aria-allowed-role/aria-allowed-role.html +++ b/test/integration/rules/aria-allowed-role/aria-allowed-role.html @@ -169,6 +169,9 @@