Skip to content

Commit

Permalink
fix(render): pretty option including extra < in the Button (#1881)
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
3 people authored Jan 30, 2025
1 parent 301f54b commit dfc49b5
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 19 deletions.
5 changes: 5 additions & 0 deletions .changeset/chilly-donkeys-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@react-email/render": patch
---

Fix extra `<` characters being kept when rendering if mso comments under certain conditions
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ exports[`email export 1`] = `
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"
target="_blank"
><span
<!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]-->
><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:18" hidden>&#8202;&#8202;</i><![endif]--></span
><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:9px"
>Join the team</span
><span
<!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]-->
><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8202;&#8203;</i><![endif]--></span
></a
>
</td>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`pretty > if mso syntax does not wrap 1`] = `
"<!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]-->
"<span
><!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]--></span
>
"
`;
Expand Down Expand Up @@ -68,12 +70,12 @@ exports[`pretty > should prettify Preview component's complex characters correct
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"
target="_blank"
><span
<!--[if mso]><i style="mso-font-width:500%;mso-text-raise:15" hidden>&#8202;</i><![endif]-->
><!--[if mso]><i style="mso-font-width:500%;mso-text-raise:15" hidden>&#8202;</i><![endif]--></span
><span
style="max-width:100%;display:inline-block;line-height:120%;mso-padding-alt:0px;mso-text-raise:7.5px"
>View your Stripe Dashboard</span
><span
<!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8203;</i><![endif]-->
><!--[if mso]><i style="mso-font-width:500%" hidden>&#8202;&#8203;</i><![endif]--></span
></a
>
<hr
Expand Down
2 changes: 1 addition & 1 deletion packages/render/src/shared/utils/pretty.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('pretty', () => {
test('if mso syntax does not wrap', async () => {
expect(
await pretty(
`<!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]-->`,
`<span><!--[if mso]><i style="mso-font-width:100%;mso-text-raise:12" hidden>&#8202;&#8202;</i><![endif]--></span>`,
),
).toMatchSnapshot();
});
Expand Down
85 changes: 72 additions & 13 deletions packages/render/src/shared/utils/pretty.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,87 @@
import type { Options, Plugin } from 'prettier';
import type { builders } from 'prettier/doc';
import html from 'prettier/plugins/html';
import { format } from 'prettier/standalone';

interface HtmlNode {
type: 'element' | 'text' | 'ieConditionalComment';
name?: string;
sourceSpan: {
start: { file: unknown[]; offset: number; line: number; col: number };
end: { file: unknown[]; offset: number; line: number; col: number };
details: null;
};
parent?: HtmlNode;
}

function recursivelyMapDoc(
doc: builders.Doc,
callback: (innerDoc: string | builders.DocCommand) => builders.Doc,
): builders.Doc {
if (Array.isArray(doc)) {
return doc.map((innerDoc) => recursivelyMapDoc(innerDoc, callback));
}

if (typeof doc === 'object') {
if (doc.type === 'group') {
return {
...doc,
contents: recursivelyMapDoc(doc.contents, callback),
expandedStates: recursivelyMapDoc(
doc.expandedStates,
callback,
) as builders.Doc[],
};
}

if ('contents' in doc) {
return {
...doc,
contents: recursivelyMapDoc(doc.contents, callback),
};
}

if ('parts' in doc) {
return {
...doc,
parts: recursivelyMapDoc(doc.parts, callback) as builders.Doc[],
};
}

if (doc.type === 'if-break') {
return {
...doc,
breakContents: recursivelyMapDoc(doc.breakContents, callback),
flatContents: recursivelyMapDoc(doc.flatContents, callback),
};
}
}

return callback(doc);
}

const modifiedHtml = { ...html } as Plugin;
if (modifiedHtml.printers) {
// eslint-disable-next-line @typescript-eslint/unbound-method
const previousPrint = modifiedHtml.printers.html.print;
modifiedHtml.printers.html.print = (path, options, print, args) => {
const node = path.getNode() as {
type: string;
sourceSpan: {
start: { file: unknown[]; offset: number; line: number; col: number };
end: { file: unknown[]; offset: number; line: number; col: number };
details: null;
};
};
const node = path.getNode() as HtmlNode;

const rawPrintingResult = previousPrint(path, options, print, args);

if (node.type === 'ieConditionalComment') {
return options.originalText.slice(
node.sourceSpan.start.offset,
node.sourceSpan.end.offset,
);
const printingResult = recursivelyMapDoc(rawPrintingResult, (doc) => {
if (typeof doc === 'object' && doc.type === 'line') {
return doc.soft ? '' : ' ';
}

return doc;
});

return printingResult;
}
return previousPrint(path, options, print, args);

return rawPrintingResult;
};
}

Expand Down

0 comments on commit dfc49b5

Please sign in to comment.