aria-prohibited-attr-evaluate.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { getRole } from '../../commons/aria';
  2. import { sanitize, subtreeText } from '../../commons/text';
  3. import standards from '../../standards';
  4. /**
  5. * Check that an element does not use any prohibited ARIA attributes.
  6. *
  7. * Prohibited attributes are taken from the `ariaAttrs` standards object from the attributes `prohibitedAttrs` property.
  8. *
  9. * ##### Data:
  10. * <table class="props">
  11. * <thead>
  12. * <tr>
  13. * <th>Type</th>
  14. * <th>Description</th>
  15. * </tr>
  16. * </thead>
  17. * <tbody>
  18. * <tr>
  19. * <td><code>String[]</code></td>
  20. * <td>List of all prohibited attributes</td>
  21. * </tr>
  22. * </tbody>
  23. * </table>
  24. *
  25. * @memberof checks
  26. * @return {Boolean} True if the element uses any prohibited ARIA attributes. False otherwise.
  27. */
  28. function ariaProhibitedAttrEvaluate(node, options = {}, virtualNode) {
  29. const extraElementsAllowedAriaLabel = options.elementsAllowedAriaLabel || [];
  30. const prohibitedList = listProhibitedAttrs(
  31. virtualNode,
  32. extraElementsAllowedAriaLabel
  33. );
  34. const prohibited = prohibitedList.filter(attrName => {
  35. if (!virtualNode.attrNames.includes(attrName)) {
  36. return false;
  37. }
  38. return sanitize(virtualNode.attr(attrName)) !== '';
  39. });
  40. if (prohibited.length === 0) {
  41. return false;
  42. }
  43. this.data(prohibited);
  44. const hasTextContent = sanitize(subtreeText(virtualNode)) !== '';
  45. // Don't fail if there is text content to announce
  46. return hasTextContent ? undefined : true;
  47. }
  48. function listProhibitedAttrs(virtualNode, elementsAllowedAriaLabel) {
  49. const role = getRole(virtualNode, { chromium: true });
  50. const roleSpec = standards.ariaRoles[role];
  51. if (roleSpec) {
  52. return roleSpec.prohibitedAttrs || [];
  53. }
  54. const { nodeName } = virtualNode.props;
  55. if (!!role || elementsAllowedAriaLabel.includes(nodeName)) {
  56. return [];
  57. }
  58. return ['aria-label', 'aria-labelledby'];
  59. }
  60. export default ariaProhibitedAttrEvaluate;