role-supports-aria-props.js 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
  4. var _ariaQuery = require("aria-query");
  5. var _jsxAstUtils = require("jsx-ast-utils");
  6. var _schemas = require("../util/schemas");
  7. var _getImplicitRole = _interopRequireDefault(require("../util/getImplicitRole"));
  8. /**
  9. * @fileoverview Enforce that elements with explicit or implicit roles defined contain only
  10. * `aria-*` properties supported by that `role`.
  11. * @author Ethan Cohen
  12. */
  13. // ----------------------------------------------------------------------------
  14. // Rule Definition
  15. // ----------------------------------------------------------------------------
  16. var errorMessage = function errorMessage(attr, role, tag, isImplicit) {
  17. if (isImplicit) {
  18. return "The attribute ".concat(attr, " is not supported by the role ").concat(role, ". This role is implicit on the element ").concat(tag, ".");
  19. }
  20. return "The attribute ".concat(attr, " is not supported by the role ").concat(role, ".");
  21. };
  22. var schema = (0, _schemas.generateObjSchema)();
  23. module.exports = {
  24. meta: {
  25. docs: {
  26. url: 'https://github.com/evcohen/eslint-plugin-jsx-a11y/tree/master/docs/rules/role-supports-aria-props.md'
  27. },
  28. schema: [schema]
  29. },
  30. create: function create(context) {
  31. return {
  32. JSXOpeningElement: function JSXOpeningElement(node) {
  33. // If role is not explicitly defined, then try and get its implicit role.
  34. var type = (0, _jsxAstUtils.elementType)(node);
  35. var role = (0, _jsxAstUtils.getProp)(node.attributes, 'role');
  36. var roleValue = role ? (0, _jsxAstUtils.getLiteralPropValue)(role) : (0, _getImplicitRole["default"])(type, node.attributes);
  37. var isImplicit = roleValue && role === undefined; // If there is no explicit or implicit role, then assume that the element
  38. // can handle the global set of aria-* properties.
  39. // This actually isn't true - should fix in future release.
  40. if (typeof roleValue !== 'string' || _ariaQuery.roles.get(roleValue) === undefined) {
  41. return;
  42. } // Make sure it has no aria-* properties defined outside of its property set.
  43. var _roles$get = _ariaQuery.roles.get(roleValue),
  44. propKeyValues = _roles$get.props;
  45. var propertySet = Object.keys(propKeyValues);
  46. var invalidAriaPropsForRole = (0, _toConsumableArray2["default"])(_ariaQuery.aria.keys()).filter(function (attribute) {
  47. return propertySet.indexOf(attribute) === -1;
  48. });
  49. node.attributes.forEach(function (prop) {
  50. // Ignore the attribute if its value is null or undefined.
  51. if ((0, _jsxAstUtils.getPropValue)(prop) == null) return; // Ignore the attribute if it's a spread.
  52. if (prop.type === 'JSXSpreadAttribute') return;
  53. var name = (0, _jsxAstUtils.propName)(prop);
  54. if (invalidAriaPropsForRole.indexOf(name) > -1) {
  55. context.report({
  56. node,
  57. message: errorMessage(name, roleValue, type, isImplicit)
  58. });
  59. }
  60. });
  61. }
  62. };
  63. }
  64. };