style-prop-object.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * @fileoverview Enforce style prop value is an object
  3. * @author David Petersen
  4. */
  5. 'use strict';
  6. const variableUtil = require('../util/variable');
  7. const docsUrl = require('../util/docsUrl');
  8. // ------------------------------------------------------------------------------
  9. // Rule Definition
  10. // ------------------------------------------------------------------------------
  11. module.exports = {
  12. meta: {
  13. docs: {
  14. description: 'Enforce style prop value is an object',
  15. category: '',
  16. recommended: false,
  17. url: docsUrl('style-prop-object')
  18. },
  19. schema: []
  20. },
  21. create: function(context) {
  22. /**
  23. * @param {object} node An Identifier node
  24. */
  25. function isNonNullaryLiteral(expression) {
  26. return expression.type === 'Literal' && expression.value !== null;
  27. }
  28. /**
  29. * @param {object} node A Identifier node
  30. */
  31. function checkIdentifiers(node) {
  32. const variable = variableUtil.variablesInScope(context).find(item => item.name === node.name);
  33. if (!variable || !variable.defs[0] || !variable.defs[0].node.init) {
  34. return;
  35. }
  36. if (isNonNullaryLiteral(variable.defs[0].node.init)) {
  37. context.report(node, 'Style prop value must be an object');
  38. }
  39. }
  40. return {
  41. CallExpression: function(node) {
  42. if (
  43. node.callee
  44. && node.callee.type === 'MemberExpression'
  45. && node.callee.property.name === 'createElement'
  46. && node.arguments.length > 1
  47. ) {
  48. if (node.arguments[1].type === 'ObjectExpression') {
  49. const style = node.arguments[1].properties.find(property => property.key && property.key.name === 'style' && !property.computed);
  50. if (style) {
  51. if (style.value.type === 'Identifier') {
  52. checkIdentifiers(style.value);
  53. } else if (isNonNullaryLiteral(style.value)) {
  54. context.report(style.value, 'Style prop value must be an object');
  55. }
  56. }
  57. }
  58. }
  59. },
  60. JSXAttribute: function(node) {
  61. if (!node.value || node.name.name !== 'style') {
  62. return;
  63. }
  64. if (node.value.type !== 'JSXExpressionContainer' || isNonNullaryLiteral(node.value.expression)) {
  65. context.report(node, 'Style prop value must be an object');
  66. } else if (node.value.expression.type === 'Identifier') {
  67. checkIdentifiers(node.value.expression);
  68. }
  69. }
  70. };
  71. }
  72. };