summaryrefslogtreecommitdiff
path: root/packages/markdown/remark/src
diff options
context:
space:
mode:
authorGravatar hippotastic <6137925+hippotastic@users.noreply.github.com> 2022-05-31 19:16:43 +0200
committerGravatar GitHub <noreply@github.com> 2022-05-31 12:16:43 -0500
commit119ecf8d469f034eaf1b1217523954d29f492cb6 (patch)
treefe952c1ee9f3b2c35b033d0a80cad33d5b93b6e5 /packages/markdown/remark/src
parente02c72f4452de76c584e06baf4696191889114bd (diff)
downloadastro-119ecf8d469f034eaf1b1217523954d29f492cb6.tar.gz
astro-119ecf8d469f034eaf1b1217523954d29f492cb6.tar.zst
astro-119ecf8d469f034eaf1b1217523954d29f492cb6.zip
Fix components in markdown regressions (#3486)
Co-authored-by: Nate Moore <natemoo-re@users.noreply.github.com>
Diffstat (limited to 'packages/markdown/remark/src')
-rw-r--r--packages/markdown/remark/src/rehype-escape.ts5
-rw-r--r--packages/markdown/remark/src/rehype-jsx.ts84
2 files changed, 46 insertions, 43 deletions
diff --git a/packages/markdown/remark/src/rehype-escape.ts b/packages/markdown/remark/src/rehype-escape.ts
index bb56166be..5cf463608 100644
--- a/packages/markdown/remark/src/rehype-escape.ts
+++ b/packages/markdown/remark/src/rehype-escape.ts
@@ -5,6 +5,11 @@ export default function rehypeEscape(): any {
return visit(node, 'element', (el) => {
if (el.tagName === 'code' || el.tagName === 'pre') {
el.properties['is:raw'] = true;
+ // Visit all raw children and escape HTML tags to prevent Markdown code
+ // like "This is a `<script>` tag" from actually opening a script tag
+ visit(el, 'raw', (raw) => {
+ raw.value = raw.value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
+ });
}
return el;
});
diff --git a/packages/markdown/remark/src/rehype-jsx.ts b/packages/markdown/remark/src/rehype-jsx.ts
index 8549b2624..46c200b70 100644
--- a/packages/markdown/remark/src/rehype-jsx.ts
+++ b/packages/markdown/remark/src/rehype-jsx.ts
@@ -1,51 +1,49 @@
-import { map } from 'unist-util-map';
+import { visit } from 'unist-util-visit';
-const MDX_ELEMENTS = new Set(['mdxJsxFlowElement', 'mdxJsxTextElement']);
+const MDX_ELEMENTS = ['mdxJsxFlowElement', 'mdxJsxTextElement'];
export default function rehypeJsx(): any {
return function (node: any): any {
- return map(node, (child: any) => {
- if (child.type === 'element') {
- return { ...child, tagName: `${child.tagName}` };
- }
- if (MDX_ELEMENTS.has(child.type)) {
- const attrs = child.attributes.reduce((acc: any[], entry: any) => {
- let attr = entry.value;
- if (attr && typeof attr === 'object') {
- attr = `{${attr.value}}`;
- } else if (attr && entry.type === 'mdxJsxExpressionAttribute') {
- attr = `{${attr}}`;
- } else if (attr === null) {
- attr = '';
- } else if (typeof attr === 'string') {
- attr = `"${attr}"`;
- }
- if (!entry.name) {
- return acc + ` ${attr}`;
- }
- return acc + ` ${entry.name}${attr ? '=' : ''}${attr}`;
- }, '');
-
- if (child.children.length === 0) {
- return {
- type: 'raw',
- value: `<${child.name}${attrs} />`,
- };
+ visit(node, 'element', (child: any) => {
+ child.tagName = `${child.tagName}`;
+ });
+ visit(node, MDX_ELEMENTS, (child: any, index: number | null, parent: any) => {
+ if (index === null || !Boolean(parent))
+ return;
+
+ const attrs = child.attributes.reduce((acc: any[], entry: any) => {
+ let attr = entry.value;
+ if (attr && typeof attr === 'object') {
+ attr = `{${attr.value}}`;
+ } else if (attr && entry.type === 'mdxJsxExpressionAttribute') {
+ attr = `{${attr}}`;
+ } else if (attr === null) {
+ attr = '';
+ } else if (typeof attr === 'string') {
+ attr = `"${attr}"`;
}
- child.children.splice(0, 0, {
- type: 'raw',
- value: `\n<${child.name}${attrs}>`,
- });
- child.children.push({
- type: 'raw',
- value: `</${child.name}>\n`,
- });
- return {
- ...child,
- type: 'element',
- tagName: `Fragment`,
- };
+ if (!entry.name) {
+ return acc + ` ${attr}`;
+ }
+ return acc + ` ${entry.name}${attr ? '=' : ''}${attr}`;
+ }, '');
+
+ if (child.children.length === 0) {
+ child.type = 'raw';
+ child.value = `<${child.name}${attrs} />`;
+ return;
}
- return child;
+
+ // Replace the current child node with its children
+ // wrapped by raw opening and closing tags
+ const openingTag = {
+ type: 'raw',
+ value: `\n<${child.name}${attrs}>`,
+ };
+ const closingTag = {
+ type: 'raw',
+ value: `</${child.name}>\n`,
+ };
+ parent.children.splice(index, 1, openingTag, ...child.children, closingTag);
});
};
}