You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

76 lines
2.3 KiB

  1. /**
  2. * @fileoverview Enforce event handler naming conventions in JSX
  3. * @author Jake Marsh
  4. */
  5. 'use strict';
  6. const docsUrl = require('../util/docsUrl');
  7. // ------------------------------------------------------------------------------
  8. // Rule Definition
  9. // ------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. docs: {
  13. description: 'Enforce event handler naming conventions in JSX',
  14. category: 'Stylistic Issues',
  15. recommended: false,
  16. url: docsUrl('jsx-handler-names')
  17. },
  18. schema: [{
  19. type: 'object',
  20. properties: {
  21. eventHandlerPrefix: {
  22. type: 'string'
  23. },
  24. eventHandlerPropPrefix: {
  25. type: 'string'
  26. }
  27. },
  28. additionalProperties: false
  29. }]
  30. },
  31. create: function(context) {
  32. const sourceCode = context.getSourceCode();
  33. const configuration = context.options[0] || {};
  34. const eventHandlerPrefix = configuration.eventHandlerPrefix || 'handle';
  35. const eventHandlerPropPrefix = configuration.eventHandlerPropPrefix || 'on';
  36. const EVENT_HANDLER_REGEX = new RegExp(`^((props\\.${eventHandlerPropPrefix})|((.*\\.)?${eventHandlerPrefix}))[A-Z].*$`);
  37. const PROP_EVENT_HANDLER_REGEX = new RegExp(`^(${eventHandlerPropPrefix}[A-Z].*|ref)$`);
  38. return {
  39. JSXAttribute: function(node) {
  40. if (!node.value || !node.value.expression || !node.value.expression.object) {
  41. return;
  42. }
  43. const propKey = typeof node.name === 'object' ? node.name.name : node.name;
  44. const propValue = sourceCode.getText(node.value.expression).replace(/^this\.|.*::/, '');
  45. if (propKey === 'ref') {
  46. return;
  47. }
  48. const propIsEventHandler = PROP_EVENT_HANDLER_REGEX.test(propKey);
  49. const propFnIsNamedCorrectly = EVENT_HANDLER_REGEX.test(propValue);
  50. if (propIsEventHandler && !propFnIsNamedCorrectly) {
  51. context.report({
  52. node: node,
  53. message: `Handler function for ${propKey} prop key must begin with '${eventHandlerPrefix}'`
  54. });
  55. } else if (propFnIsNamedCorrectly && !propIsEventHandler) {
  56. context.report({
  57. node: node,
  58. message: `Prop key for ${propValue} must begin with '${eventHandlerPropPrefix}'`
  59. });
  60. }
  61. }
  62. };
  63. }
  64. };