jsx-no-literals.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /**
  2. * @fileoverview Prevent using string literals in React component definition
  3. * @author Caleb Morris
  4. * @author David Buchan-Swanson
  5. */
  6. 'use strict';
  7. const docsUrl = require('../util/docsUrl');
  8. // ------------------------------------------------------------------------------
  9. // Rule Definition
  10. // ------------------------------------------------------------------------------
  11. module.exports = {
  12. meta: {
  13. docs: {
  14. description: 'Prevent using string literals in React component definition',
  15. category: 'Stylistic Issues',
  16. recommended: false,
  17. url: docsUrl('jsx-no-literals')
  18. },
  19. schema: [{
  20. type: 'object',
  21. properties: {
  22. noStrings: {
  23. type: 'boolean'
  24. }
  25. },
  26. additionalProperties: false
  27. }]
  28. },
  29. create: function(context) {
  30. const isNoStrings = context.options[0] ? context.options[0].noStrings : false;
  31. const message = isNoStrings ?
  32. 'Strings not allowed in JSX files' :
  33. 'Missing JSX expression container around literal string';
  34. function reportLiteralNode(node) {
  35. context.report({
  36. node: node,
  37. message: message
  38. });
  39. }
  40. function getParentIgnoringBinaryExpressions(node) {
  41. let current = node;
  42. while (current.parent.type === 'BinaryExpression') {
  43. current = current.parent;
  44. }
  45. return current.parent;
  46. }
  47. function getValidation(node) {
  48. const parent = getParentIgnoringBinaryExpressions(node);
  49. const standard = !/^[\s]+$/.test(node.value) &&
  50. typeof node.value === 'string' &&
  51. parent.type.indexOf('JSX') !== -1 &&
  52. parent.type !== 'JSXAttribute';
  53. if (isNoStrings) {
  54. return standard;
  55. }
  56. return standard && parent.type !== 'JSXExpressionContainer';
  57. }
  58. // --------------------------------------------------------------------------
  59. // Public
  60. // --------------------------------------------------------------------------
  61. return {
  62. Literal: function(node) {
  63. if (getValidation(node)) {
  64. reportLiteralNode(node);
  65. }
  66. },
  67. JSXText: function(node) {
  68. if (getValidation(node)) {
  69. reportLiteralNode(node);
  70. }
  71. },
  72. TemplateLiteral: function(node) {
  73. const parent = getParentIgnoringBinaryExpressions(node);
  74. if (isNoStrings && parent.type === 'JSXExpressionContainer') {
  75. reportLiteralNode(node);
  76. }
  77. }
  78. };
  79. }
  80. };