mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-04 20:57:17 +02:00
fix(mdx-loader): improve mdxJsxTextElementToHtml (#9262)
This commit is contained in:
parent
b3c8f5c929
commit
9868babf75
3 changed files with 45 additions and 5 deletions
|
@ -7,3 +7,5 @@
|
||||||
## <i>HTML</i>
|
## <i>HTML</i>
|
||||||
|
|
||||||
## `inline.code()`
|
## `inline.code()`
|
||||||
|
|
||||||
|
## some <span className="some-class" style={{border: "solid"}}>styled</span> <strong>heading</strong> <span class="myClass" className="myClassName <> weird char" data-random-attr="456"/> test
|
||||||
|
|
|
@ -171,6 +171,11 @@ exports[`toc remark plugin works on non text phrasing content 1`] = `
|
||||||
value: '<code>inline.code()</code>',
|
value: '<code>inline.code()</code>',
|
||||||
id: 'inlinecode',
|
id: 'inlinecode',
|
||||||
level: 2
|
level: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'some <span class="some-class">styled</span> <strong>heading</strong> <span class="myClassName <> weird char"></span> test',
|
||||||
|
id: 'some-styled-heading--test',
|
||||||
|
level: 2
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -183,6 +188,8 @@ exports[`toc remark plugin works on non text phrasing content 1`] = `
|
||||||
## <i>HTML</i>
|
## <i>HTML</i>
|
||||||
|
|
||||||
## \`inline.code()\`
|
## \`inline.code()\`
|
||||||
|
|
||||||
|
## some <span className="some-class" style={{border: "solid"}}>styled</span> <strong>heading</strong> <span class="myClass" className="myClassName <> weird char" data-random-attr="456" /> test
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -8,26 +8,57 @@
|
||||||
import escapeHtml from 'escape-html';
|
import escapeHtml from 'escape-html';
|
||||||
import type {Parent} from 'unist';
|
import type {Parent} from 'unist';
|
||||||
import type {PhrasingContent, Heading} from 'mdast';
|
import type {PhrasingContent, Heading} from 'mdast';
|
||||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
import type {
|
||||||
import type {MdxJsxAttributeValueExpression} from 'mdast-util-mdx';
|
MdxJsxAttribute,
|
||||||
|
MdxJsxAttributeValueExpression,
|
||||||
|
MdxJsxTextElement,
|
||||||
|
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||||
|
} from 'mdast-util-mdx';
|
||||||
|
|
||||||
export function stringifyContent(
|
export function stringifyContent(
|
||||||
node: Parent,
|
node: Parent,
|
||||||
toString: (param: unknown) => string, // TODO weird but works): string {
|
toString: (param: unknown) => string, // TODO weird but works
|
||||||
): string {
|
): string {
|
||||||
return (node.children as PhrasingContent[])
|
return (node.children as PhrasingContent[])
|
||||||
.map((item) => toValue(item, toString))
|
.map((item) => toValue(item, toString))
|
||||||
.join('');
|
.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO This is really a workaround, and not super reliable
|
||||||
|
// For now we only support serializing tagName, className and content
|
||||||
|
// Can we implement the TOC with real JSX nodes instead of html strings later?
|
||||||
|
function mdxJsxTextElementToHtml(
|
||||||
|
element: MdxJsxTextElement,
|
||||||
|
toString: (param: unknown) => string, // TODO weird but works
|
||||||
|
): string {
|
||||||
|
const tag = element.name;
|
||||||
|
|
||||||
|
const attributes = element.attributes.filter(
|
||||||
|
(child): child is MdxJsxAttribute => child.type === 'mdxJsxAttribute',
|
||||||
|
);
|
||||||
|
|
||||||
|
const classAttribute =
|
||||||
|
attributes.find((attr) => attr.name === 'className') ??
|
||||||
|
attributes.find((attr) => attr.name === 'class');
|
||||||
|
|
||||||
|
const classAttributeString = classAttribute
|
||||||
|
? `class="${escapeHtml(String(classAttribute.value))}"`
|
||||||
|
: ``;
|
||||||
|
|
||||||
|
const allAttributes = classAttributeString ? ` ${classAttributeString}` : '';
|
||||||
|
|
||||||
|
const content = stringifyContent(element, toString);
|
||||||
|
|
||||||
|
return `<${tag}${allAttributes}>${content}</${tag}>`;
|
||||||
|
}
|
||||||
|
|
||||||
export function toValue(
|
export function toValue(
|
||||||
node: PhrasingContent | Heading,
|
node: PhrasingContent | Heading,
|
||||||
toString: (param: unknown) => string, // TODO weird but works
|
toString: (param: unknown) => string, // TODO weird but works
|
||||||
): string {
|
): string {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case 'mdxJsxTextElement': {
|
case 'mdxJsxTextElement': {
|
||||||
const tag = node.name;
|
return mdxJsxTextElementToHtml(node as MdxJsxTextElement, toString);
|
||||||
return `<${tag}>${stringifyContent(node, toString)}</${tag}>`;
|
|
||||||
}
|
}
|
||||||
case 'text':
|
case 'text':
|
||||||
return escapeHtml(node.value);
|
return escapeHtml(node.value);
|
||||||
|
|
Loading…
Add table
Reference in a new issue