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:
Nate Moore 2021-06-29 15:33:56 -05:00 committed by GitHub
parent 8b4760c24f
commit f721275f33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 56 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Fix issue where Markdown could close it's parent element early (#494)

View file

@ -1,4 +1,5 @@
---
const { content } = Astro.props;
---
<html>

View 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>

View file

@ -509,6 +509,12 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
async function pushMarkdownToBuffer() {
const md = buffers.markdown;
const { markdownOptions = {} } = astroConfig;
if (!md.trim()) {
buffers.out += ',' + md;
buffers.markdown = '';
curr = 'out';
return;
}
const { $scope: scopedClassName } = state.markers.insideMarkdown as Record<'$scope', any>;
let { content: rendered } = await renderMarkdown(dedent(md), {
...(markdownOptions as AstroMarkdownOptions),
@ -627,7 +633,8 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
if (componentName === 'Markdown') {
const { $scope } = attributes ?? {};
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') {
await pushMarkdownToBuffer();
}
@ -717,7 +724,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
case 'Body':
case 'Title':
case 'Element': {
if (state.markers.insideMarkdown) {
if (curr === 'markdown') {
await pushMarkdownToBuffer();
}
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) {
state.markers.insideMarkdown = false;
}
const hasAttrs = (node.attributes.filter(({ name }: Attribute) => name !== '$scope')).length > 0;
if (hasAttrs) {
return;
}
}
if (curr === 'markdown' && buffers.markdown !== '') {
await pushMarkdownToBuffer();

View file

@ -82,4 +82,12 @@ Markdown('Renders dynamic content though the content attribute', async ({ runtim
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();

View 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>