-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Hoist hydration script out of slot templates (#4891)
* Hoist hydration script out of slot templates * Add changeset * Fix HTML components * Mark as html string
- Loading branch information
Showing
13 changed files
with
165 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'astro': patch | ||
--- | ||
|
||
Hoist hydration scripts out of slot templates |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import type { RenderInstruction } from './types.js'; | ||
import type { SSRResult } from '../../../@types/astro.js'; | ||
|
||
import { renderChild } from './any.js'; | ||
import { HTMLString, markHTMLString } from '../escape.js'; | ||
|
||
export class SlotString extends HTMLString { | ||
public instructions: null | RenderInstruction[]; | ||
constructor(content: string, instructions: null | RenderInstruction[]) { | ||
super(content); | ||
this.instructions = instructions; | ||
} | ||
} | ||
|
||
export async function renderSlot(_result: any, slotted: string, fallback?: any): Promise<string> { | ||
if (slotted) { | ||
let iterator = renderChild(slotted); | ||
let content = ''; | ||
let instructions: null | RenderInstruction[] = null; | ||
for await (const chunk of iterator) { | ||
if ((chunk as any).type === 'directive') { | ||
if(instructions === null) { | ||
instructions = []; | ||
} | ||
instructions.push(chunk); | ||
} else { | ||
content += chunk; | ||
} | ||
} | ||
return markHTMLString(new SlotString(content, instructions)); | ||
} | ||
return fallback; | ||
} | ||
|
||
interface RenderSlotsResult { | ||
slotInstructions: null | RenderInstruction[], | ||
children: Record<string, string>; | ||
} | ||
|
||
export async function renderSlots(result: SSRResult, slots: any = {}): Promise<RenderSlotsResult> { | ||
let slotInstructions: RenderSlotsResult['slotInstructions'] = null; | ||
let children: RenderSlotsResult['children'] = {}; | ||
if (slots) { | ||
await Promise.all( | ||
Object.entries(slots).map(([key, value]) => | ||
renderSlot(result, value as string).then((output: any) => { | ||
if(output.instructions) { | ||
if(slotInstructions === null) { | ||
slotInstructions = []; | ||
} | ||
slotInstructions.push(...output.instructions); | ||
} | ||
children[key] = output; | ||
}) | ||
) | ||
); | ||
} | ||
return { slotInstructions, children }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { expect } from 'chai'; | ||
import * as cheerio from 'cheerio'; | ||
import { loadFixture } from './test-utils.js'; | ||
|
||
describe('Nested Slots', () => { | ||
let fixture; | ||
|
||
before(async () => { | ||
fixture = await loadFixture({ root: './fixtures/astro-slots-nested/' }); | ||
await fixture.build(); | ||
}); | ||
|
||
it('Hidden nested slots see their hydration scripts hoisted', async () => { | ||
const html = await fixture.readFile('/hidden-nested/index.html'); | ||
const $ = cheerio.load(html); | ||
expect($('script')).to.have.a.lengthOf(1, 'script rendered'); | ||
const scriptInTemplate = $($('template')[0].children[0]).find('script'); | ||
expect(scriptInTemplate).to.have.a.lengthOf(0, 'script defined outside of the inner template'); | ||
}); | ||
}); |
6 changes: 6 additions & 0 deletions
6
packages/astro/test/fixtures/astro-slots-nested/astro.config.mjs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import { defineConfig } from 'astro/config'; | ||
import react from '@astrojs/react'; | ||
|
||
export default defineConfig({ | ||
integrations: [react()] | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "@test/astro-slots-nested", | ||
"version": "0.0.0", | ||
"private": true, | ||
"dependencies": { | ||
"astro": "workspace:*", | ||
"@astrojs/react": "workspace:*" | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
packages/astro/test/fixtures/astro-slots-nested/src/components/Inner.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function Inner() { | ||
return <span>Inner</span>; | ||
} |
19 changes: 19 additions & 0 deletions
19
packages/astro/test/fixtures/astro-slots-nested/src/components/Parent.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { useState, useEffect } from 'react'; | ||
|
||
export default function Parent({ children }) { | ||
const [show, setShow] = useState(false); | ||
|
||
useEffect(() => { | ||
console.log('mount'); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<p> | ||
<input type="checkbox" value={show} onChange={() => setShow(!show)} /> | ||
Toggle show (true should show "Inner") | ||
</p> | ||
{show ? children : 'Nothing'} | ||
</> | ||
); | ||
} |
18 changes: 18 additions & 0 deletions
18
packages/astro/test/fixtures/astro-slots-nested/src/pages/hidden-nested.astro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
import Parent from '../components/Parent' | ||
import Inner from '../components/Inner' | ||
--- | ||
|
||
<html lang="en"> | ||
<head> | ||
<title>Testing</title> | ||
</head> | ||
<body> | ||
<main> | ||
<!-- Try to remove client:load to see it work --> | ||
<Parent client:load> | ||
<Inner client:load /> | ||
</Parent> | ||
</main> | ||
</body> | ||
</html> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.