From 27a7ded08be7299417ccebddfd25fa39bda99e77 Mon Sep 17 00:00:00 2001 From: Kenneth Skovhus Date: Sun, 24 Apr 2022 17:47:21 +0200 Subject: [PATCH] fix: JSX attribute parsing issue when using double quotes (#1226) --- packages/macro/src/macroJsx.ts | 29 +++++++++++++++++------------ packages/macro/test/jsx-trans.ts | 13 +++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/packages/macro/src/macroJsx.ts b/packages/macro/src/macroJsx.ts index f31dd1e57..bddd6547f 100644 --- a/packages/macro/src/macroJsx.ts +++ b/packages/macro/src/macroJsx.ts @@ -51,6 +51,21 @@ export default class MacroJSX { this.elementIndex = makeCounter() } + safeJsxAttribute = (name: string, value: string) => { + // Quoted JSX attributes use XML-style escapes instead of JavaScript-style escapes. + // This means that is invalid, but is valid. + + // We could consider removing this condition and always wrap in a jsxExpressionContainer. + const attributeValue = value.includes('"') + ? this.types.jsxExpressionContainer(this.types.stringLiteral(value)) + : this.types.stringLiteral(value) + + return this.types.jsxAttribute( + this.types.jsxIdentifier(name), + attributeValue + ) + } + replacePath = (path: NodePath) => { const tokens = this.tokenizeNode(path.node) @@ -78,21 +93,11 @@ export default class MacroJSX { if (process.env.NODE_ENV !== "production") { if (message) { - attributes.push( - this.types.jsxAttribute( - this.types.jsxIdentifier(MESSAGE), - this.types.stringLiteral(message) - ) - ) + attributes.push(this.safeJsxAttribute(MESSAGE, message)) } } } else { - attributes.push( - this.types.jsxAttribute( - this.types.jsxIdentifier(ID), - this.types.stringLiteral(message) - ) - ) + attributes.push(this.safeJsxAttribute(ID, message)) } if (process.env.NODE_ENV !== "production") { diff --git a/packages/macro/test/jsx-trans.ts b/packages/macro/test/jsx-trans.ts index d5282d18b..950f9fc4f 100644 --- a/packages/macro/test/jsx-trans.ts +++ b/packages/macro/test/jsx-trans.ts @@ -92,6 +92,19 @@ export default [ }} />; `, }, + { + name: "Quoted JSX attributes are handled", + input: ` + import { Trans } from '@lingui/macro'; + Speak "friend"!; + Speak "friend"!; + `, + expected: ` + import { Trans } from "@lingui/react"; + ; + ; + `, + }, { name: "Template literals as children", input: `