Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow conditional rendering when RenderScript is enabled #1057

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/grumpy-ads-know.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@astrojs/compiler": patch
---

Allows conditional rendering of scripts when `RenderScript` is enabled
MoustaphaDev marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@

[TestPrinter/script_external_in_expression_(renderScript:_false) - 1]
## Input

```
<main>{<script src="./hello.js"></script>}
```

## Output

```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";

export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });

const $$Index = $$createComponent(($$result, $$props, $$slots) => {

return $$render`${$$maybeRenderHead($$result)}<main>${$$render`<script src="./hello.js"></script>`}</main>`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---

[TestPrinter/script_external_in_expression_(renderScript:_false)#01 - 1]
## Input

```
<main>{false && <script>console.log("hello")</script>}
```

## Output

```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";

export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });

const $$Index = $$createComponent(($$result, $$props, $$slots) => {

return $$render`${$$maybeRenderHead($$result)}<main>${false && $$render`<script>console.log("hello")</script>`}</main>`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

[TestPrinter/script_external_in_expression_(renderScript:_true) - 1]
## Input

```
<main>{<script src="./hello.js"></script>}
```

## Output

```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";

export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'external', src: './hello.js' }] });

const $$Index = $$createComponent(($$result, $$props, $$slots) => {

return $$render`${$$maybeRenderHead($$result)}<main>${$$render`${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`}</main>`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

[TestPrinter/script_in_expression_(renderScript:_false) - 1]
## Input

```
<main>{false && <script>console.log("hello")</script>}
```

## Output

```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";

export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });

const $$Index = $$createComponent(($$result, $$props, $$slots) => {

return $$render`${$$maybeRenderHead($$result)}<main>${false && $$render`<script>console.log("hello")</script>`}</main>`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@

[TestPrinter/script_in_expression_(renderScript:_true) - 1]
## Input

```
<main>{true && <script>console.log("hello")</script>}
```

## Output

```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";

export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("hello")` }] });

const $$Index = $$createComponent(($$result, $$props, $$slots) => {

return $$render`${$$maybeRenderHead($$result)}<main>${true && $$render`${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`}</main>`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
30 changes: 28 additions & 2 deletions internal/printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,34 @@ import Widget2 from '../components/Widget2.astro';
},
filename: "/src/pages/index.astro",
},
{
name: "script external in expression (renderScript: true)",
source: `<main>{<script src="./hello.js"></script>}`,
transformOptions: transform.TransformOptions{
RenderScript: true,
},
filename: "/src/pages/index.astro",
},
{
// maintain the original behavior, though it may be
// unneeded as renderScript is now on by default
name: "script external in expression (renderScript: false)",
source: `<main>{<script src="./hello.js"></script>}`,
filename: "/src/pages/index.astro",
},
{
name: "script in expression (renderScript: true)",
source: `<main>{true && <script>console.log("hello")</script>}`,
transformOptions: transform.TransformOptions{
RenderScript: true,
},
filename: "/src/pages/index.astro",
},
{
name: "script in expression (renderScript: false)",
source: `<main>{false && <script>console.log("hello")</script>}`,
filename: "/src/pages/index.astro",
},
{
name: "script inline (renderScript: true)",
source: `<main><script is:inline type="module">console.log("Hello");</script>`,
Expand Down Expand Up @@ -2092,7 +2120,6 @@ const meta = { title: 'My App' };
Kind: test_utils.JsOutput,
FolderName: "__printer_js__",
})

})
}
}
Expand Down Expand Up @@ -2215,7 +2242,6 @@ const c = '\''
code := test_utils.Dedent(tt.source)

doc, err := astro.ParseWithOptions(strings.NewReader(code), astro.ParseOptionEnableLiteral(true), astro.ParseOptionWithHandler(&handler.Handler{}))

if err != nil {
t.Error(err)
}
Expand Down
5 changes: 3 additions & 2 deletions internal/transform/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func ExtractStyles(doc *astro.Node) {
return
}
// Ignore styles in svg/noscript/etc
if !IsHoistable(n) {
if !IsHoistable(n, false) {
return
}
// prepend node to maintain authored order
Expand Down Expand Up @@ -403,7 +403,8 @@ func ExtractScript(doc *astro.Node, n *astro.Node, opts *TransformOptions, h *ha
return
}
// Ignore scripts in svg/noscript/etc
if !IsHoistable(n) {
// In expressions ignore scripts, unless `RenderScript` is true
if !IsHoistable(n, opts.RenderScript) {
return
}

Expand Down
7 changes: 6 additions & 1 deletion internal/transform/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ func GetAttr(n *astro.Node, key string) *astro.Attribute {
return nil
}

func IsHoistable(n *astro.Node) bool {
func IsHoistable(n *astro.Node, renderScriptEnabled bool) bool {
parent := n.Closest(func(p *astro.Node) bool {
return p.DataAtom == atom.Svg || p.DataAtom == atom.Noscript || p.DataAtom == atom.Template
})

if renderScriptEnabled && parent != nil && parent.Expression {
return true
}

return parent == nil
}

Expand Down
Loading