1/** 2 * @fileoverview A rule to ensure consistent quotes used in jsx syntax. 3 * @author Mathias Schreck <https://github.com/lo1tuma> 4 */ 5 6"use strict"; 7 8//------------------------------------------------------------------------------ 9// Requirements 10//------------------------------------------------------------------------------ 11 12const astUtils = require("./utils/ast-utils"); 13 14//------------------------------------------------------------------------------ 15// Constants 16//------------------------------------------------------------------------------ 17 18const QUOTE_SETTINGS = { 19 "prefer-double": { 20 quote: "\"", 21 description: "singlequote", 22 convert(str) { 23 return str.replace(/'/gu, "\""); 24 } 25 }, 26 "prefer-single": { 27 quote: "'", 28 description: "doublequote", 29 convert(str) { 30 return str.replace(/"/gu, "'"); 31 } 32 } 33}; 34 35//------------------------------------------------------------------------------ 36// Rule Definition 37//------------------------------------------------------------------------------ 38 39module.exports = { 40 meta: { 41 type: "layout", 42 43 docs: { 44 description: "enforce the consistent use of either double or single quotes in JSX attributes", 45 category: "Stylistic Issues", 46 recommended: false, 47 url: "https://eslint.org/docs/rules/jsx-quotes" 48 }, 49 50 fixable: "whitespace", 51 52 schema: [ 53 { 54 enum: ["prefer-single", "prefer-double"] 55 } 56 ], 57 messages: { 58 unexpected: "Unexpected usage of {{description}}." 59 } 60 }, 61 62 create(context) { 63 const quoteOption = context.options[0] || "prefer-double", 64 setting = QUOTE_SETTINGS[quoteOption]; 65 66 /** 67 * Checks if the given string literal node uses the expected quotes 68 * @param {ASTNode} node A string literal node. 69 * @returns {boolean} Whether or not the string literal used the expected quotes. 70 * @public 71 */ 72 function usesExpectedQuotes(node) { 73 return node.value.indexOf(setting.quote) !== -1 || astUtils.isSurroundedBy(node.raw, setting.quote); 74 } 75 76 return { 77 JSXAttribute(node) { 78 const attributeValue = node.value; 79 80 if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { 81 context.report({ 82 node: attributeValue, 83 messageId: "unexpected", 84 data: { 85 description: setting.description 86 }, 87 fix(fixer) { 88 return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); 89 } 90 }); 91 } 92 } 93 }; 94 } 95}; 96