Skip to content

Commit 8cae811

Browse files
fix: allow conditional rendering when RenderScript is enabled (#1057)
* test: add test cases * fix: allow processing scripts in expressions when `RenderScript` is enabled * test: add test case without src attribute * fix: add `nil` parent guard * test: add new snapshots * chore: changeset * test: remove duplicate snapshot * apply sarah's changeset suggestion Co-authored-by: Sarah Rainsberger <[email protected]> --------- Co-authored-by: Sarah Rainsberger <[email protected]>
1 parent 71fb3ef commit 8cae811

8 files changed

+208
-5
lines changed

Diff for: .changeset/grumpy-ads-know.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@astrojs/compiler": patch
3+
---
4+
5+
Fixes an issue with the conditional rendering of scripts.
6+
7+
**This change updates a v5.0 breaking change when `experimental.directRenderScript` became the default script handling behavior.** If you have already successfully upgraded to Astro v5, you may need to review your script tags again and make sure they still behave as desired after this release. [See the v5 Upgrade Guide for more details.](https://docs.astro.build/en/guides/upgrade-to/v5/#script-tags-are-rendered-directly-as-declared)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/script_external_in_expression_(renderScript:_false) - 1]
3+
## Input
4+
5+
```
6+
<main>{<script src="./hello.js"></script>}
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
34+
35+
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<main>${$$render`<script src="./hello.js"></script>`}</main>`;
38+
}, '/src/pages/index.astro', undefined);
39+
export default $$Index;
40+
```
41+
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/script_external_in_expression_(renderScript:_true) - 1]
3+
## Input
4+
5+
```
6+
<main>{<script src="./hello.js"></script>}
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'external', src: './hello.js' }] });
34+
35+
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<main>${$$render`${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`}</main>`;
38+
}, '/src/pages/index.astro', undefined);
39+
export default $$Index;
40+
```
41+
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/script_in_expression_(renderScript:_false) - 1]
3+
## Input
4+
5+
```
6+
<main>{false && <script>console.log("hello")</script>}
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
34+
35+
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<main>${false && $$render`<script>console.log("hello")</script>`}</main>`;
38+
}, '/src/pages/index.astro', undefined);
39+
export default $$Index;
40+
```
41+
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
[TestPrinter/script_in_expression_(renderScript:_true) - 1]
3+
## Input
4+
5+
```
6+
<main>{true && <script>console.log("hello")</script>}
7+
```
8+
9+
## Output
10+
11+
```js
12+
import {
13+
Fragment,
14+
render as $$render,
15+
createAstro as $$createAstro,
16+
createComponent as $$createComponent,
17+
renderComponent as $$renderComponent,
18+
renderHead as $$renderHead,
19+
maybeRenderHead as $$maybeRenderHead,
20+
unescapeHTML as $$unescapeHTML,
21+
renderSlot as $$renderSlot,
22+
mergeSlots as $$mergeSlots,
23+
addAttribute as $$addAttribute,
24+
spreadAttributes as $$spreadAttributes,
25+
defineStyleVars as $$defineStyleVars,
26+
defineScriptVars as $$defineScriptVars,
27+
renderTransition as $$renderTransition,
28+
createTransitionScope as $$createTransitionScope,
29+
renderScript as $$renderScript,
30+
createMetadata as $$createMetadata
31+
} from "http://localhost:3000/";
32+
33+
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("hello")` }] });
34+
35+
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
36+
37+
return $$render`${$$maybeRenderHead($$result)}<main>${true && $$render`${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`}</main>`;
38+
}, '/src/pages/index.astro', undefined);
39+
export default $$Index;
40+
```
41+
---

Diff for: internal/printer/printer_test.go

+28-2
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,34 @@ import Widget2 from '../components/Widget2.astro';
894894
},
895895
filename: "/src/pages/index.astro",
896896
},
897+
{
898+
name: "script external in expression (renderScript: true)",
899+
source: `<main>{<script src="./hello.js"></script>}`,
900+
transformOptions: transform.TransformOptions{
901+
RenderScript: true,
902+
},
903+
filename: "/src/pages/index.astro",
904+
},
905+
{
906+
// maintain the original behavior, though it may be
907+
// unneeded as renderScript is now on by default
908+
name: "script external in expression (renderScript: false)",
909+
source: `<main>{<script src="./hello.js"></script>}`,
910+
filename: "/src/pages/index.astro",
911+
},
912+
{
913+
name: "script in expression (renderScript: true)",
914+
source: `<main>{true && <script>console.log("hello")</script>}`,
915+
transformOptions: transform.TransformOptions{
916+
RenderScript: true,
917+
},
918+
filename: "/src/pages/index.astro",
919+
},
920+
{
921+
name: "script in expression (renderScript: false)",
922+
source: `<main>{false && <script>console.log("hello")</script>}`,
923+
filename: "/src/pages/index.astro",
924+
},
897925
{
898926
name: "script inline (renderScript: true)",
899927
source: `<main><script is:inline type="module">console.log("Hello");</script>`,
@@ -2092,7 +2120,6 @@ const meta = { title: 'My App' };
20922120
Kind: test_utils.JsOutput,
20932121
FolderName: "__printer_js__",
20942122
})
2095-
20962123
})
20972124
}
20982125
}
@@ -2215,7 +2242,6 @@ const c = '\''
22152242
code := test_utils.Dedent(tt.source)
22162243

22172244
doc, err := astro.ParseWithOptions(strings.NewReader(code), astro.ParseOptionEnableLiteral(true), astro.ParseOptionWithHandler(&handler.Handler{}))
2218-
22192245
if err != nil {
22202246
t.Error(err)
22212247
}

Diff for: internal/transform/transform.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func ExtractStyles(doc *astro.Node) {
122122
return
123123
}
124124
// Ignore styles in svg/noscript/etc
125-
if !IsHoistable(n) {
125+
if !IsHoistable(n, false) {
126126
return
127127
}
128128
// prepend node to maintain authored order
@@ -403,7 +403,8 @@ func ExtractScript(doc *astro.Node, n *astro.Node, opts *TransformOptions, h *ha
403403
return
404404
}
405405
// Ignore scripts in svg/noscript/etc
406-
if !IsHoistable(n) {
406+
// In expressions ignore scripts, unless `RenderScript` is true
407+
if !IsHoistable(n, opts.RenderScript) {
407408
return
408409
}
409410

Diff for: internal/transform/utils.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,15 @@ func GetAttr(n *astro.Node, key string) *astro.Attribute {
4747
return nil
4848
}
4949

50-
func IsHoistable(n *astro.Node) bool {
50+
func IsHoistable(n *astro.Node, renderScriptEnabled bool) bool {
5151
parent := n.Closest(func(p *astro.Node) bool {
5252
return p.DataAtom == atom.Svg || p.DataAtom == atom.Noscript || p.DataAtom == atom.Template
5353
})
54+
55+
if renderScriptEnabled && parent != nil && parent.Expression {
56+
return true
57+
}
58+
5459
return parent == nil
5560
}
5661

0 commit comments

Comments
 (0)