123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /**
- * @fileoverview Enforce style prop value is an object
- * @author David Petersen
- */
- 'use strict';
- const variableUtil = require('../util/variable');
- const docsUrl = require('../util/docsUrl');
- // ------------------------------------------------------------------------------
- // Rule Definition
- // ------------------------------------------------------------------------------
- module.exports = {
- meta: {
- docs: {
- description: 'Enforce style prop value is an object',
- category: 'Possible Errors',
- recommended: false,
- url: docsUrl('style-prop-object')
- },
- messages: {
- stylePropNotObject: 'Style prop value must be an object'
- },
- schema: [
- {
- type: 'object',
- properties: {
- allow: {
- type: 'array',
- items: {
- type: 'string'
- },
- additionalItems: false,
- uniqueItems: true
- }
- }
- }
- ]
- },
- create(context) {
- const allowed = new Set(((context.options.length > 0) && context.options[0].allow) || []);
- /**
- * @param {ASTNode} expression An Identifier node
- * @returns {boolean}
- */
- function isNonNullaryLiteral(expression) {
- return expression.type === 'Literal' && expression.value !== null;
- }
- /**
- * @param {object} node A Identifier node
- */
- function checkIdentifiers(node) {
- const variable = variableUtil.variablesInScope(context).find((item) => item.name === node.name);
- if (!variable || !variable.defs[0] || !variable.defs[0].node.init) {
- return;
- }
- if (isNonNullaryLiteral(variable.defs[0].node.init)) {
- context.report({
- node,
- messageId: 'stylePropNotObject'
- });
- }
- }
- return {
- CallExpression(node) {
- if (
- node.callee
- && node.callee.type === 'MemberExpression'
- && node.callee.property.name === 'createElement'
- && node.arguments.length > 1
- ) {
- if (node.arguments[0].name) {
- // store name of component
- const componentName = node.arguments[0].name;
- // allowed list contains the name
- if (allowed.has(componentName)) {
- // abort operation
- return;
- }
- }
- if (node.arguments[1].type === 'ObjectExpression') {
- const style = node.arguments[1].properties.find((property) => property.key && property.key.name === 'style' && !property.computed);
- if (style) {
- if (style.value.type === 'Identifier') {
- checkIdentifiers(style.value);
- } else if (isNonNullaryLiteral(style.value)) {
- context.report({
- node: style.value,
- messageId: 'stylePropNotObject'
- });
- }
- }
- }
- }
- },
- JSXAttribute(node) {
- if (!node.value || node.name.name !== 'style') {
- return;
- }
- // store parent element
- const parentElement = node.parent;
- // parent element is a JSXOpeningElement
- if (parentElement && parentElement.type === 'JSXOpeningElement') {
- // get the name of the JSX element
- const name = parentElement.name && parentElement.name.name;
- // allowed list contains the name
- if (allowed.has(name)) {
- // abort operation
- return;
- }
- }
- if (node.value.type !== 'JSXExpressionContainer' || isNonNullaryLiteral(node.value.expression)) {
- context.report({
- node,
- messageId: 'stylePropNotObject'
- });
- } else if (node.value.expression.type === 'Identifier') {
- checkIdentifiers(node.value.expression);
- }
- }
- };
- }
- };
|