jsx-equals-spacing.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /**
  2. * @fileoverview Disallow or enforce spaces around equal signs in JSX attributes.
  3. * @author ryym
  4. */
  5. 'use strict';
  6. const docsUrl = require('../util/docsUrl');
  7. // ------------------------------------------------------------------------------
  8. // Rule Definition
  9. // ------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. docs: {
  13. description: 'Disallow or enforce spaces around equal signs in JSX attributes',
  14. category: 'Stylistic Issues',
  15. recommended: false,
  16. url: docsUrl('jsx-equals-spacing')
  17. },
  18. fixable: 'code',
  19. schema: [{
  20. enum: ['always', 'never']
  21. }]
  22. },
  23. create: function(context) {
  24. const config = context.options[0];
  25. const sourceCode = context.getSourceCode();
  26. /**
  27. * Determines a given attribute node has an equal sign.
  28. * @param {ASTNode} attrNode - The attribute node.
  29. * @returns {boolean} Whether or not the attriute node has an equal sign.
  30. */
  31. function hasEqual(attrNode) {
  32. return attrNode.type !== 'JSXSpreadAttribute' && attrNode.value !== null;
  33. }
  34. // --------------------------------------------------------------------------
  35. // Public
  36. // --------------------------------------------------------------------------
  37. return {
  38. JSXOpeningElement: function(node) {
  39. node.attributes.forEach(attrNode => {
  40. if (!hasEqual(attrNode)) {
  41. return;
  42. }
  43. const equalToken = sourceCode.getTokenAfter(attrNode.name);
  44. const spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken);
  45. const spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value);
  46. switch (config) {
  47. default:
  48. case 'never':
  49. if (spacedBefore) {
  50. context.report({
  51. node: attrNode,
  52. loc: equalToken.loc.start,
  53. message: 'There should be no space before \'=\'',
  54. fix: function(fixer) {
  55. return fixer.removeRange([attrNode.name.range[1], equalToken.range[0]]);
  56. }
  57. });
  58. }
  59. if (spacedAfter) {
  60. context.report({
  61. node: attrNode,
  62. loc: equalToken.loc.start,
  63. message: 'There should be no space after \'=\'',
  64. fix: function(fixer) {
  65. return fixer.removeRange([equalToken.range[1], attrNode.value.range[0]]);
  66. }
  67. });
  68. }
  69. break;
  70. case 'always':
  71. if (!spacedBefore) {
  72. context.report({
  73. node: attrNode,
  74. loc: equalToken.loc.start,
  75. message: 'A space is required before \'=\'',
  76. fix: function(fixer) {
  77. return fixer.insertTextBefore(equalToken, ' ');
  78. }
  79. });
  80. }
  81. if (!spacedAfter) {
  82. context.report({
  83. node: attrNode,
  84. loc: equalToken.loc.start,
  85. message: 'A space is required after \'=\'',
  86. fix: function(fixer) {
  87. return fixer.insertTextAfter(equalToken, ' ');
  88. }
  89. });
  90. }
  91. break;
  92. }
  93. });
  94. }
  95. };
  96. }
  97. };