Skip to content

Commit

Permalink
fix: JSX attribute parsing issue when using double quotes (#1226)
Browse files Browse the repository at this point in the history
  • Loading branch information
skovhus authored Apr 24, 2022
1 parent d272bc2 commit 27a7ded
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 12 deletions.
29 changes: 17 additions & 12 deletions packages/macro/src/macroJsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Trans id="Say \"hi\"!" /> is invalid, but <Trans id={"Say \"hi\"!"} /> 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)

Expand Down Expand Up @@ -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") {
Expand Down
13 changes: 13 additions & 0 deletions packages/macro/test/jsx-trans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ export default [
}} />;
`,
},
{
name: "Quoted JSX attributes are handled",
input: `
import { Trans } from '@lingui/macro';
<Trans>Speak "friend"!</Trans>;
<Trans id="custom-id">Speak "friend"!</Trans>;
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id={'Speak "friend"!'} />;
<Trans id="custom-id" message={'Speak "friend"!'} />;
`,
},
{
name: "Template literals as children",
input: `
Expand Down

0 comments on commit 27a7ded

Please sign in to comment.