mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
fix(rendering): prevent removal of necessary <astro-slot>
elements (#10317)
* fix(rendering): prevent removal of necessary `<astro-slot>` elements * add test * add changeset * missed a spot * adjust test * assume `supportsAstroStaticSlot` * bring back accidentally removed `markHTMLString` call
This commit is contained in:
parent
3de48e8f62
commit
33583e8b31
7 changed files with 56 additions and 5 deletions
5
.changeset/thick-geckos-design.md
Normal file
5
.changeset/thick-geckos-design.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"astro": patch
|
||||
---
|
||||
|
||||
Fixes an issue where elements slotted within interactive framework components disappeared after hydration.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
const Tag = 'div';
|
||||
---
|
||||
<Tag>
|
||||
<slot />
|
||||
</Tag>
|
|
@ -0,0 +1,4 @@
|
|||
<script>
|
||||
export let id;
|
||||
</script>
|
||||
<div {id}>Slot goes here:<slot /></div>
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
import Poly from '../components/Poly.astro';
|
||||
import Stuff from '../components/Stuff.svelte';
|
||||
---
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
|
||||
<Poly>
|
||||
<Stuff client:load id="hydratable">poo</Stuff>
|
||||
</Poly>
|
||||
|
||||
<Poly>
|
||||
<Stuff id="ssr-only">bar</Stuff>
|
||||
</Poly>
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,6 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { prepareTestFactory } from './shared-component-tests.js';
|
||||
import { waitForHydrate } from './test-utils.js';
|
||||
|
||||
const { test, createTests } = prepareTestFactory({ root: './fixtures/svelte-component/' });
|
||||
|
||||
|
@ -35,3 +36,13 @@ test.describe('Svelte components lifecycle', () => {
|
|||
expect((await toggle.textContent()).trim()).toBe('open');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test.describe('Slotting content into svelte components', () => {
|
||||
test('should stay after hydration', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/with-slots'));
|
||||
const hydratableElement = page.locator('#hydratable');
|
||||
await waitForHydrate(page, hydratableElement);
|
||||
await expect(hydratableElement).toHaveText("Slot goes here:poo");
|
||||
});
|
||||
});
|
||||
|
|
|
@ -67,7 +67,8 @@ function isHTMLComponent(Component: unknown) {
|
|||
|
||||
const ASTRO_SLOT_EXP = /<\/?astro-slot\b[^>]*>/g;
|
||||
const ASTRO_STATIC_SLOT_EXP = /<\/?astro-static-slot\b[^>]*>/g;
|
||||
function removeStaticAstroSlot(html: string, supportsAstroStaticSlot: boolean) {
|
||||
|
||||
function removeStaticAstroSlot(html: string, supportsAstroStaticSlot = true) {
|
||||
const exp = supportsAstroStaticSlot ? ASTRO_STATIC_SLOT_EXP : ASTRO_SLOT_EXP;
|
||||
return html.replace(exp, '');
|
||||
}
|
||||
|
@ -310,7 +311,7 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
|
|||
} else if (html && html.length > 0) {
|
||||
destination.write(
|
||||
markHTMLString(
|
||||
removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot ?? false)
|
||||
removeStaticAstroSlot(html, renderer?.ssr?.supportsAstroStaticSlot)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -391,7 +392,8 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr
|
|||
})
|
||||
);
|
||||
}
|
||||
destination.write(markHTMLString(renderElement('astro-island', island, false)));
|
||||
const renderedElement = renderElement('astro-island', island, false);
|
||||
destination.write(markHTMLString(renderedElement));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ describe('Slots with client: directives', () => {
|
|||
assert.equal($('script').length, 1);
|
||||
});
|
||||
|
||||
it('Astro slot tags are cleaned', async () => {
|
||||
it('Astro slot tags are kept', async () => {
|
||||
const html = await fixture.readFile('/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
assert.equal($('astro-slot').length, 0);
|
||||
assert.equal($('astro-slot').length, 1);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue