Skip to content

Commit caa49b3

Browse files
gabrielmfernbukinoshitadependabot[bot]
committed
fix(render): pretty option including extra < in the Button (#1881)
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Bu Kinoshita <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent b44c937 commit caa49b3

File tree

5 files changed

+85
-19
lines changed

5 files changed

+85
-19
lines changed

.changeset/chilly-donkeys-worry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-email/render": patch
3+
---
4+
5+
Fix extra `<` characters being kept when rendering if mso comments under certain conditions

packages/react-email/src/cli/commands/testing/__snapshots__/export.spec.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ exports[`email export 1`] = `
130130
style="background-color:rgb(0,0,0);border-radius:0.25rem;color:rgb(255,255,255);font-size:12px;font-weight:600;text-decoration-line:none;text-align:center;padding-left:1.25rem;padding-right:1.25rem;padding-top:0.75rem;padding-bottom:0.75rem;line-height:100%;text-decoration:none;display:inline-block;max-width:100%;mso-padding-alt:0px;padding:12px 20px 12px 20px"
131131
target="_blank"
132132
><span
133-
<!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]-->
133+
><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]--></span
134134
><span
135135
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px"
136136
>Join the team</span
137137
><span
138-
<!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]-->
138+
><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span
139139
></a
140140
>
141141
</td>

packages/render/src/shared/utils/__snapshots__/pretty.spec.ts.snap

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

33
exports[`pretty > if mso syntax does not wrap 1`] = `
4-
"<!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]-->
4+
"<span
5+
><!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]--></span
6+
>
57
"
68
`;
79
@@ -68,12 +70,12 @@ exports[`pretty > should prettify Preview component's complex characters correct
6870
style="line-height:100%;text-decoration:none;display:block;max-width:100%;mso-padding-alt:0px;background-color:#656ee8;border-radius:5px;color:#fff;font-size:16px;font-weight:bold;text-align:center;width:100%;padding:10px 10px 10px 10px"
6971
target="_blank"
7072
><span
71-
<!--[if mso]><i style="mso-font-width:500%;mso-text-raise:15" hidden>&#8202;</i><![endif]-->
73+
><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:15" hidden>&#8202;</i><![endif]--></span
7274
><span
7375
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:7.5px"
7476
>View your Stripe Dashboard</span
7577
><span
76-
<!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8203;</i><![endif]-->
78+
><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8203;</i><![endif]--></span
7779
></a
7880
>
7981
<hr

packages/render/src/shared/utils/pretty.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('pretty', () => {
1515
test('if mso syntax does not wrap', async () => {
1616
expect(
1717
await pretty(
18-
`<!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]-->`,
18+
`<span><!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]--></span>`,
1919
),
2020
).toMatchSnapshot();
2121
});

packages/render/src/shared/utils/pretty.ts

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,87 @@
11
import type { Options, Plugin } from 'prettier';
2+
import type { builders } from 'prettier/doc';
23
import html from 'prettier/plugins/html';
34
import { format } from 'prettier/standalone';
45

6+
interface HtmlNode {
7+
type: 'element' | 'text' | 'ieConditionalComment';
8+
name?: string;
9+
sourceSpan: {
10+
start: { file: unknown[]; offset: number; line: number; col: number };
11+
end: { file: unknown[]; offset: number; line: number; col: number };
12+
details: null;
13+
};
14+
parent?: HtmlNode;
15+
}
16+
17+
function recursivelyMapDoc(
18+
doc: builders.Doc,
19+
callback: (innerDoc: string | builders.DocCommand) => builders.Doc,
20+
): builders.Doc {
21+
if (Array.isArray(doc)) {
22+
return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));
23+
}
24+
25+
if (typeof doc === 'object') {
26+
if (doc.type === 'group') {
27+
return {
28+
...doc,
29+
contents: recursivelyMapDoc(doc.contents, callback),
30+
expandedStates: recursivelyMapDoc(
31+
doc.expandedStates,
32+
callback,
33+
) as builders.Doc[],
34+
};
35+
}
36+
37+
if ('contents' in doc) {
38+
return {
39+
...doc,
40+
contents: recursivelyMapDoc(doc.contents, callback),
41+
};
42+
}
43+
44+
if ('parts' in doc) {
45+
return {
46+
...doc,
47+
parts: recursivelyMapDoc(doc.parts, callback) as builders.Doc[],
48+
};
49+
}
50+
51+
if (doc.type === 'if-break') {
52+
return {
53+
...doc,
54+
breakContents: recursivelyMapDoc(doc.breakContents, callback),
55+
flatContents: recursivelyMapDoc(doc.flatContents, callback),
56+
};
57+
}
58+
}
59+
60+
return callback(doc);
61+
}
62+
563
const modifiedHtml = { ...html } as Plugin;
664
if (modifiedHtml.printers) {
765
// eslint-disable-next-line @typescript-eslint/unbound-method
866
const previousPrint = modifiedHtml.printers.html.print;
967
modifiedHtml.printers.html.print = (path, options, print, args) => {
10-
const node = path.getNode() as {
11-
type: string;
12-
sourceSpan: {
13-
start: { file: unknown[]; offset: number; line: number; col: number };
14-
end: { file: unknown[]; offset: number; line: number; col: number };
15-
details: null;
16-
};
17-
};
68+
const node = path.getNode() as HtmlNode;
69+
70+
const rawPrintingResult = previousPrint(path, options, print, args);
1871

1972
if (node.type === 'ieConditionalComment') {
20-
return options.originalText.slice(
21-
node.sourceSpan.start.offset,
22-
node.sourceSpan.end.offset,
23-
);
73+
const printingResult = recursivelyMapDoc(rawPrintingResult, (doc) => {
74+
if (typeof doc === 'object' && doc.type === 'line') {
75+
return doc.soft ? '' : ' ';
76+
}
77+
78+
return doc;
79+
});
80+
81+
return printingResult;
2482
}
25-
return previousPrint(path, options, print, args);
83+
84+
return rawPrintingResult;
2685
};
2786
}
2887

0 commit comments

Comments
 (0)