Skip to content

Commit

Permalink
fix: JSX attribute parsing issue when using html entities (#1234)
Browse files Browse the repository at this point in the history
* Handle html entities in macro

* Update test expectations
  • Loading branch information
skovhus committed Jun 22, 2022
1 parent 71ffc32 commit 98e9332
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 39 deletions.
11 changes: 2 additions & 9 deletions packages/macro/src/macroJsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,10 @@ export default class MacroJSX {
}

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)

// This handles quoted JSX attributes and html entities.
return this.types.jsxAttribute(
this.types.jsxIdentifier(name),
attributeValue
this.types.jsxExpressionContainer(this.types.stringLiteral(value))
)
}

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 13 additions & 4 deletions packages/macro/test/jsx-plural.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="{count, plural, offset:1 =0 {Zero items} few {{count} items} other {<0>A lot of them</0>}}" values={{
<Trans id={
"{count, plural, offset:1 =0 {Zero items} few {{count} items} other {<0>A lot of them</0>}}"
}
values={{
count: count
}} components={{
0: <a href="/more" />
Expand All @@ -38,7 +41,10 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="{count, plural, one {<0>#</0> slot added} other {<1>#</1> slots added}}" values={{
<Trans id={
"{count, plural, one {<0>#</0> slot added} other {<1>#</1> slots added}}"
}
values={{
count: count
}} components={{
0: <strong />,
Expand All @@ -61,7 +67,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans render="strong" id="msg.plural" message="{count, plural, offset:1 =0 {Zero items} few {{count} items} other {<0>A lot of them</0>}}" values={{
<Trans render="strong" id="msg.plural" message={"{count, plural, offset:1 =0 {Zero items} few {{count} items} other {<0>A lot of them</0>}}"} values={{
count: count
}} components={{
0: <a href="/more" />
Expand All @@ -84,7 +90,10 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="inner-id-removed" message="Looking for {0, plural, offset:1 =0 {zero items} few {{1} items {2}} other {<0>a lot of them</0>}}" values={{
<Trans id="inner-id-removed" message={
"Looking for {0, plural, offset:1 =0 {zero items} few {{1} items {2}} other {<0>a lot of them</0>}}"
}
values={{
0: items.length,
1: items.length,
2: 42
Expand Down
4 changes: 2 additions & 2 deletions packages/macro/test/jsx-select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="{count, select, male {He} female {She} other {<0>Other</0>}}" values={{
<Trans id={"{count, select, male {He} female {She} other {<0>Other</0>}}"} values={{
count: count
}} components={{
0: <strong />
Expand All @@ -32,7 +32,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans render="strong" id="msg.select" message="{0, select, male {He} female {She} other {<0>Other</0>}}" values={{
<Trans render="strong" id="msg.select" message={"{0, select, male {He} female {She} other {<0>Other</0>}}"} values={{
0: user.gender
}} components={{
0: <strong />
Expand Down
10 changes: 8 additions & 2 deletions packages/macro/test/jsx-selectOrdinal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="This is my {count, selectordinal, one {#st} two {#nd} other {<0>#rd</0>}} cat." values={{
<Trans id={
"This is my {count, selectordinal, one {#st} two {#nd} other {<0>#rd</0>}} cat."
}
values={{
count: count
}} components={{
0: <strong />
Expand All @@ -34,7 +37,10 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="This is my {0, selectordinal, one {#st} two {#nd} other {<0>#rd</0>}} cat." values={{
<Trans id={
"This is my {0, selectordinal, one {#st} two {#nd} other {<0>#rd</0>}} cat."
}
values={{
0: user.numCats
}} components={{
0: <strong />
Expand Down
59 changes: 38 additions & 21 deletions packages/macro/test/jsx-trans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Hello World" />;
<Trans id={"Hello World"} />;
`,
},
{
Expand All @@ -18,7 +18,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Hello World" />;
<Trans id={"Hello World"} />;
`,
},
{
Expand All @@ -29,7 +29,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="msg.hello" message="Hello World" />;
<Trans id="msg.hello" message={"Hello World"} />;
`,
},
{
Expand All @@ -40,7 +40,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="msg.hello" message="Hello World" />;
<Trans id="msg.hello" message={"Hello World"} />;
`,
},
{
Expand All @@ -51,7 +51,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="msg.hello" message="Hello World" />;
<Trans id="msg.hello" message={"Hello World"} />;
`,
},
{
Expand All @@ -73,7 +73,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Hi {yourName}, my name is {myName}" values={{
<Trans id={"Hi {yourName}, my name is {myName}"} values={{
yourName: yourName,
myName: myName,
}} />;
Expand All @@ -87,7 +87,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="{duplicate} variable {duplicate}" values={{
<Trans id={"{duplicate} variable {duplicate}"} values={{
duplicate: duplicate
}} />;
`,
Expand All @@ -105,6 +105,23 @@ export default [
<Trans id="custom-id" message={'Speak "friend"!'} />;
`,
},
{
name: "HTML attributes are handled",
input: `
import { Trans } from '@lingui/macro';
<Trans>
<Text>This should work &nbsp;</Text>
</Trans>;
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id={"<0>This should work \\xA0</0>"}
components={{
0: <Text />,
}}
/>;
`,
},
{
name: "Template literals as children",
input: `
Expand All @@ -113,7 +130,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="How much is {expression}? {count}" values={{
<Trans id={"How much is {expression}? {count}"} values={{
expression: expression,
count: count
}} />;
Expand All @@ -127,7 +144,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="hello {count, plural, one {world} other {worlds}}" />;
<Trans id={"hello {count, plural, one {world} other {worlds}}"} />;
`,
},
{
Expand All @@ -145,7 +162,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Property {0}, function {1}, array {2}, constant {3}, object {4}, everything {5}" values={{
<Trans id={"Property {0}, function {1}, array {2}, constant {3}, object {4}, everything {5}"} values={{
0: props.name,
1: random(),
2: array[index],
Expand All @@ -169,7 +186,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Hello <0>World!</0><1/><2>My name is <3> <4>{name}</4></3></2>" values={{
<Trans id={"Hello <0>World!</0><1/><2>My name is <3> <4>{name}</4></3></2>"} values={{
name: name
}} components={{
0: <strong />,
Expand All @@ -188,7 +205,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="<0>Component inside expression container</0>" components={{
<Trans id={"<0>Component inside expression container</0>"} components={{
0: <span />
}} />;
`,
Expand All @@ -201,7 +218,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="<0/>" components={{
<Trans id={"<0/>"} components={{
0: <br />
}} />;
`,
Expand All @@ -222,7 +239,7 @@ export default [
production: true,
input: `
import { Trans } from '@lingui/macro';
<Trans id="msg.hello" comment="Hello World">Hello World</Trans>
<Trans id="msg.hello" comment="Hello World">Hello World</Trans>
`,
expected: `
import { Trans } from "@lingui/react";
Expand Down Expand Up @@ -255,7 +272,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Strip whitespace around arguments: '{name}'" values={{
<Trans id={"Strip whitespace around arguments: '{name}'"} values={{
name: name
}} />;
`,
Expand All @@ -272,7 +289,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Strip whitespace around tags, but keep <0>forced spaces</0>!" components={{
<Trans id={"Strip whitespace around tags, but keep <0>forced spaces</0>!"} components={{
0: <strong />
}} />;
`,
Expand All @@ -288,7 +305,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Keep forced\\n newlines!" />;
<Trans id={"Keep forced\\n newlines!"} />;
`,
},
{
Expand All @@ -303,7 +320,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Keep multiple\\n forced\\n newlines!" />;
<Trans id={"Keep multiple\\n forced\\n newlines!"} />;
`,
},
{
Expand All @@ -314,7 +331,7 @@ export default [
expected: `
import { Trans } from "@lingui/react";
import { i18n } from "@lingui/core";
<Trans id="Read <0>more</0>" components={{
<Trans id={"Read <0>more</0>"} components={{
0: <a href="/more" title={
/*i18n*/
i18n._("Full content of {articleName}", {
Expand Down Expand Up @@ -350,7 +367,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="Hello World" />;
<Trans id={"Hello World"} />;
`,
},
{
Expand All @@ -361,7 +378,7 @@ export default [
`,
expected: `
import { Trans } from "@lingui/react";
<Trans id="&" />;
<Trans id={"&"} />;
`,
},
]

1 comment on commit 98e9332

@vercel
Copy link

@vercel vercel bot commented on 98e9332 Jun 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.