Fix <Markdown {content} />
closing parent tag (#575)
* test(#494): add failing test * chore: update with-markdown example * fix(#494): avoid early close with <Markdown content /> * chore: add changeset
This commit is contained in:
parent
8b4760c24f
commit
f721275f33
6 changed files with 56 additions and 2 deletions
5
.changeset/warm-terms-admire.md
Normal file
5
.changeset/warm-terms-admire.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix issue where Markdown could close it's parent element early (#494)
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
const { content } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
17
examples/with-markdown/src/pages/external.astro
Normal file
17
examples/with-markdown/src/pages/external.astro
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
import { Markdown } from 'astro/components';
|
||||||
|
import Layout from '../layouts/main.astro';
|
||||||
|
|
||||||
|
const title = `External Markdown`;
|
||||||
|
const content = `Markdown *content* to render`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout content={{ title }}>
|
||||||
|
<main>
|
||||||
|
<div>
|
||||||
|
<Markdown {content} />
|
||||||
|
<p>Some other stuff</p>
|
||||||
|
</div>
|
||||||
|
<p>Lastly...</p>
|
||||||
|
</main>
|
||||||
|
</Layout>
|
|
@ -509,6 +509,12 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
|
||||||
async function pushMarkdownToBuffer() {
|
async function pushMarkdownToBuffer() {
|
||||||
const md = buffers.markdown;
|
const md = buffers.markdown;
|
||||||
const { markdownOptions = {} } = astroConfig;
|
const { markdownOptions = {} } = astroConfig;
|
||||||
|
if (!md.trim()) {
|
||||||
|
buffers.out += ',' + md;
|
||||||
|
buffers.markdown = '';
|
||||||
|
curr = 'out';
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { $scope: scopedClassName } = state.markers.insideMarkdown as Record<'$scope', any>;
|
const { $scope: scopedClassName } = state.markers.insideMarkdown as Record<'$scope', any>;
|
||||||
let { content: rendered } = await renderMarkdown(dedent(md), {
|
let { content: rendered } = await renderMarkdown(dedent(md), {
|
||||||
...(markdownOptions as AstroMarkdownOptions),
|
...(markdownOptions as AstroMarkdownOptions),
|
||||||
|
@ -627,7 +633,8 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
|
||||||
if (componentName === 'Markdown') {
|
if (componentName === 'Markdown') {
|
||||||
const { $scope } = attributes ?? {};
|
const { $scope } = attributes ?? {};
|
||||||
state.markers.insideMarkdown = typeof state.markers.insideMarkdown === 'object' ? { $scope, count: state.markers.insideMarkdown.count + 1 } : { $scope, count: 1 };
|
state.markers.insideMarkdown = typeof state.markers.insideMarkdown === 'object' ? { $scope, count: state.markers.insideMarkdown.count + 1 } : { $scope, count: 1 };
|
||||||
if (attributes.content) {
|
const keys = Object.keys(attributes).filter(attr => attr !== '$scope');
|
||||||
|
if (keys.length > 0) {
|
||||||
if (curr === 'markdown') {
|
if (curr === 'markdown') {
|
||||||
await pushMarkdownToBuffer();
|
await pushMarkdownToBuffer();
|
||||||
}
|
}
|
||||||
|
@ -717,7 +724,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
|
||||||
case 'Body':
|
case 'Body':
|
||||||
case 'Title':
|
case 'Title':
|
||||||
case 'Element': {
|
case 'Element': {
|
||||||
if (state.markers.insideMarkdown) {
|
if (curr === 'markdown') {
|
||||||
await pushMarkdownToBuffer();
|
await pushMarkdownToBuffer();
|
||||||
}
|
}
|
||||||
if (paren !== -1) {
|
if (paren !== -1) {
|
||||||
|
@ -732,6 +739,10 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
|
||||||
if ((state.markers.insideMarkdown as Record<string, any>).count <= 0) {
|
if ((state.markers.insideMarkdown as Record<string, any>).count <= 0) {
|
||||||
state.markers.insideMarkdown = false;
|
state.markers.insideMarkdown = false;
|
||||||
}
|
}
|
||||||
|
const hasAttrs = (node.attributes.filter(({ name }: Attribute) => name !== '$scope')).length > 0;
|
||||||
|
if (hasAttrs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (curr === 'markdown' && buffers.markdown !== '') {
|
if (curr === 'markdown' && buffers.markdown !== '') {
|
||||||
await pushMarkdownToBuffer();
|
await pushMarkdownToBuffer();
|
||||||
|
|
|
@ -82,4 +82,12 @@ Markdown('Renders dynamic content though the content attribute', async ({ runtim
|
||||||
assert.ok($('#inner').is('[class]'), 'Scoped class passed down');
|
assert.ok($('#inner').is('[class]'), 'Scoped class passed down');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Markdown('Does not close parent early when using content attribute (#494)', async ({ runtime }) => {
|
||||||
|
const result = await runtime.load('/close');
|
||||||
|
if (result.error) throw new Error(result.error);
|
||||||
|
|
||||||
|
const $ = doc(result.contents);
|
||||||
|
assert.equal($('#target').children().length, 2, '<Markdown content /> closed div#target early');
|
||||||
|
});
|
||||||
|
|
||||||
Markdown.run();
|
Markdown.run();
|
||||||
|
|
12
packages/astro/test/fixtures/astro-markdown/src/pages/close.astro
vendored
Normal file
12
packages/astro/test/fixtures/astro-markdown/src/pages/close.astro
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
---
|
||||||
|
import { Markdown } from 'astro/components';
|
||||||
|
const content = `Markdown *content* to render`;
|
||||||
|
---
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<div id="target">
|
||||||
|
<Markdown content={content} />
|
||||||
|
<p>Some other stuff</p>
|
||||||
|
</div>
|
||||||
|
<p>Lastly...</p>
|
||||||
|
</main>
|
Loading…
Reference in a new issue