Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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/poor-maps-fly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/compiler': patch
---

Fix edge case with Fragment parsing in head, add `fragment` node to AST output
3 changes: 3 additions & 0 deletions internal/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,9 @@ func inHeadIM(p *parser) bool {
return true
}
p.tok.Data = s
} else if p.oe.top() != nil && (isComponent(p.oe.top().Data) || isFragment((p.oe.top().Data))) {
p.addText(p.tok.Data)
return true
}
case StartTagToken:
// Allow components in Head
Expand Down
6 changes: 5 additions & 1 deletion internal/printer/print-to-json.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ASTPoint struct {

type ASTNode struct {
Type string `json:"type"`
Name string `json:"name,omitempty"`
Name string `json:"name"`
Value string `json:"value,omitempty"`
Attributes []ASTNode `json:"attributes,omitempty"`
Directives []ASTNode `json:"directives,omitempty"`
Expand Down Expand Up @@ -59,6 +59,8 @@ func (n ASTNode) String() string {
}
if n.Name != "" {
str += fmt.Sprintf(`,"name":"%s"`, escapeForJSON(n.Name))
} else if n.Type == "fragment" {
str += `,"name":""`
}
if n.Value != "" || n.Type == "attribute" {
str += fmt.Sprintf(`,"value":"%s"`, escapeForJSON(n.Value))
Expand Down Expand Up @@ -201,6 +203,8 @@ func renderNode(p *printer, parent *ASTNode, n *Node, opts t.ParseOptions) {
node.Type = "component"
} else if n.CustomElement {
node.Type = "custom-element"
} else if n.Fragment {
node.Type = "fragment"
} else {
node.Type = "element"
}
Expand Down
24 changes: 24 additions & 0 deletions internal/printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1244,6 +1244,20 @@ import { Container, Col, Row } from 'react-bootstrap';
code: `<body>${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `<div>Default</div><div>Named</div>` + BACKTICK + `,})}</body>`,
},
},
{
name: "Fragment shorthand only",
source: `<>Hello</>`,
want: want{
code: `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `Hello` + BACKTICK + `,})}`,
},
},
{
name: "Fragment literal only",
source: `<Fragment>world</Fragment>`,
want: want{
code: `${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render` + BACKTICK + `world` + BACKTICK + `,})}`,
},
},
{
name: "Fragment slotted",
source: `<body><Component><><div>Default</div><div>Named</div></></Component></body>`,
Expand Down Expand Up @@ -1905,6 +1919,16 @@ func TestPrintToJSON(t *testing.T) {
source: `<!-- hello -->`,
want: []ASTNode{{Type: "comment", Value: " hello "}},
},
{
name: "Fragment Shorthand",
source: `<>Hello</>`,
want: []ASTNode{{Type: "fragment", Name: "", Children: []ASTNode{{Type: "text", Value: "Hello"}}}},
},
{
name: "Fragment Literal",
source: `<Fragment>World</Fragment>`,
want: []ASTNode{{Type: "fragment", Name: "Fragment", Children: []ASTNode{{Type: "text", Value: "World"}}}},
},
{
name: "Frontmatter",
source: `---
Expand Down
Binary file modified lib/compiler/deno/astro.wasm
Binary file not shown.
25 changes: 25 additions & 0 deletions lib/compiler/test/parse-fragment.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable no-console */

import { parse } from '@astrojs/compiler';

const src = `<>Hello</><Fragment>World</Fragment>`;

async function run() {
const result = await parse(src);

const [first, second] = result.ast.children;
if (first.type !== 'fragment') {
throw new Error(`Expected first child node to be of type "fragment"`);
}
if (first.name !== '') {
throw new Error(`Expected first child node to have name of ""`);
}
if (second.type !== 'fragment') {
throw new Error(`Expected second child node to be of type "fragment"`);
}
if (second.name !== 'Fragment') {
throw new Error(`Expected second child node to have name of "Fragment"`);
}
}

await run();
1 change: 1 addition & 0 deletions lib/compiler/test/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ import './script-fragment.test.mjs';
import './top-level-expression.test.mjs';
import './stress.test.mjs';
import './parse.test.mjs';
import './parse-fragment.test.mjs';
import './parse-ii.test.mjs';
import './render-head.test.mjs';