diff --git a/docs/rules/string-content.md b/docs/rules/string-content.md index d651937fba..fd3e0909c0 100644 --- a/docs/rules/string-content.md +++ b/docs/rules/string-content.md @@ -6,6 +6,13 @@ This rule is fixable. *It only reports one pattern per AST node at the time.* +This rule ignores the following tagged template literals as they're known to contain code: + +- ``gql`…` `` +- ``html`…` `` +- ``svg`…` `` +- ``styled.*`…` `` + ## Fail ```js diff --git a/rules/string-content.js b/rules/string-content.js index 2fb7832921..64ea86ce4d 100644 --- a/rules/string-content.js +++ b/rules/string-content.js @@ -8,6 +8,40 @@ const defaultPatterns = { '\'': '’' }; +const ignoredIdentifier = new Set([ + 'gql', + 'html', + 'svg' +]); + +const ignoredMemberExpressionObject = new Set([ + 'styled' +]); + +const isIgnoredTag = node => { + if (!node.parent || !node.parent.parent || !node.parent.parent.tag) { + return false; + } + + const {tag} = node.parent.parent; + + if (tag.type === 'Identifier' && ignoredIdentifier.has(tag.name)) { + return true; + } + + if (tag.type === 'MemberExpression') { + const {object} = tag; + if ( + object.type === 'Identifier' && + ignoredMemberExpressionObject.has(object.name) + ) { + return true; + } + } + + return false; +}; + const defaultMessage = 'Prefer `{{suggest}}` over `{{match}}`.'; function getReplacements(patterns) { @@ -53,7 +87,7 @@ const create = context => { if (typeof string !== 'string') { return; } - } else { + } else if (!isIgnoredTag(node)) { string = node.value.raw; } diff --git a/test/string-content.js b/test/string-content.js index 40e2435a57..4b603427ed 100644 --- a/test/string-content.js +++ b/test/string-content.js @@ -41,7 +41,28 @@ ruleTester.run('string-content', rule, { // `TemplateLiteral` 'const foo = `🦄`', // Should not escape - 'const foo = `\\`\\${1}`' + 'const foo = `\\`\\${1}`', + // Ignored + ` + const foo = gql\`{ + field(input: '...') + }\`; + `, + ` + const foo = styled.div\` + background: url('...') + \`; + `, + ` + const foo = html\` +
...
+ \`; + `, + ` + const foo = svg\` + + \`; + ` /* eslint-enable no-template-curly-in-string */ ], invalid: [ @@ -198,6 +219,12 @@ ruleTester.run('string-content', rule, { output: 'const foo = `\\\\\\${bar}`', options: [{patterns: {foo: '{bar}'}}], errors: createError('foo', '{bar}') + }, + // Not ignored tag + { + code: 'const foo = notIgnoredTag`\'`', + output: 'const foo = notIgnoredTag`’`', + errors: createError('\'', '’') } /* eslint-enable no-template-curly-in-string */ ]