From 35c70fe9fef9095a779897090949998f4b85e732 Mon Sep 17 00:00:00 2001
From: Moustapha HappyDev
Date: Mon, 9 Jun 2025 23:52:27 +0000
Subject: [PATCH 01/13] test: correct wrong test inputs
---
internal/printer/__printer_js__/slot_with_fallback.snap | 2 +-
internal/printer/printer_test.go | 2 +-
internal/transform/transform_test.go | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/internal/printer/__printer_js__/slot_with_fallback.snap b/internal/printer/__printer_js__/slot_with_fallback.snap
index 45e425c8c..dcbf747a0 100755
--- a/internal/printer/__printer_js__/slot_with_fallback.snap
+++ b/internal/printer/__printer_js__/slot_with_fallback.snap
@@ -3,7 +3,7 @@
## Input
```
-Hello world!
+Hello world!
```
## Output
diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go
index fedea94a3..ef736f3d1 100644
--- a/internal/printer/printer_test.go
+++ b/internal/printer/printer_test.go
@@ -185,7 +185,7 @@ func TestPrinter(t *testing.T) {
},
{
name: "slot with fallback",
- source: `Hello world!
`,
+ source: `Hello world!
`,
},
{
name: "slot with fallback II",
diff --git a/internal/transform/transform_test.go b/internal/transform/transform_test.go
index 1da0cbe2b..961be6353 100644
--- a/internal/transform/transform_test.go
+++ b/internal/transform/transform_test.go
@@ -390,7 +390,7 @@ func TestCompactTransform(t *testing.T) {
},
{
name: "remove whitespace only",
- source: ` `,
+ source: ` `,
want: ``,
},
{
From 7efdc94ffbf84754e5ae41e3faa80adfecb2c068 Mon Sep 17 00:00:00 2001
From: Moustapha HappyDev
Date: Mon, 9 Jun 2025 23:59:17 +0000
Subject: [PATCH 02/13] test: fix incorrectly closed tags in inputs
---
.../Self-closing_components_in_head_can_have_siblings.snap | 2 +-
.../__printer_js__/Self-closing_script_in_head_works.snap | 2 +-
internal/printer/printer_test.go | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/internal/printer/__printer_js__/Self-closing_components_in_head_can_have_siblings.snap b/internal/printer/__printer_js__/Self-closing_components_in_head_can_have_siblings.snap
index e11dfd4ed..1624a4796 100755
--- a/internal/printer/__printer_js__/Self-closing_components_in_head_can_have_siblings.snap
+++ b/internal/printer/__printer_js__/Self-closing_components_in_head_can_have_siblings.snap
@@ -3,7 +3,7 @@
## Input
```
-
+
```
## Output
diff --git a/internal/printer/__printer_js__/Self-closing_script_in_head_works.snap b/internal/printer/__printer_js__/Self-closing_script_in_head_works.snap
index ec156d5ec..bb6a9de31 100755
--- a/internal/printer/__printer_js__/Self-closing_script_in_head_works.snap
+++ b/internal/printer/__printer_js__/Self-closing_script_in_head_works.snap
@@ -3,7 +3,7 @@
## Input
```
-
+
```
## Output
diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go
index ef736f3d1..530921330 100644
--- a/internal/printer/printer_test.go
+++ b/internal/printer/printer_test.go
@@ -1001,7 +1001,7 @@ const name = 'world';
},
{
name: "Self-closing script in head works",
- source: ``,
+ source: ``,
},
{
name: "Self-closing title",
@@ -1013,7 +1013,7 @@ const name = 'world';
},
{
name: "Self-closing components in head can have siblings",
- source: ``,
+ source: ``,
},
{
name: "Self-closing formatting elements",
From 697f08c5141b6ab9c78a386ad5f09714f595fe9d Mon Sep 17 00:00:00 2001
From: Moustapha HappyDev
Date: Tue, 10 Jun 2025 01:11:32 +0000
Subject: [PATCH 03/13] feat: implement exact literal HTML parsing mode
This commit introduces the foundations for a more precise HTML parsing mode that preserves the original document structure more faithfully, as much as possible, and instead let the browser fix invalid HTML itself.
---
internal/doctype.go | 50 +++++++++++
internal/parser.go | 119 +++++++++++++++++++++++++-
internal/transform/scope-css_test.go | 9 +-
internal/transform/scope-html_test.go | 2 -
internal/transform/transform_test.go | 27 +++++-
5 files changed, 198 insertions(+), 9 deletions(-)
diff --git a/internal/doctype.go b/internal/doctype.go
index 934abf91c..faba7e0be 100644
--- a/internal/doctype.go
+++ b/internal/doctype.go
@@ -154,3 +154,53 @@ var quirkyIDs = []string{
"-//webtechs//dtd mozilla html 2.0//",
"-//webtechs//dtd mozilla html//",
}
+
+func parseDoctypeExact(s string) (n *Node) {
+ n = &Node{Type: DoctypeNode}
+
+ // Find the name.
+ space := strings.IndexAny(s, whitespace)
+ if space == -1 {
+ space = len(s)
+ }
+ n.Data = s[:space]
+ n.Data = strings.ToLower(n.Data)
+ s = strings.TrimLeft(s[space:], whitespace)
+
+ if len(s) < 6 {
+ // It can't start with "PUBLIC" or "SYSTEM".
+ // Ignore the rest of the string.
+ return n
+ }
+
+ key := strings.ToLower(s[:6])
+ s = s[6:]
+ for key == "public" || key == "system" {
+ s = strings.TrimLeft(s, whitespace)
+ if s == "" {
+ break
+ }
+ quote := s[0]
+ if quote != '"' && quote != '\'' {
+ break
+ }
+ s = s[1:]
+ q := strings.IndexRune(s, rune(quote))
+ var id string
+ if q == -1 {
+ id = s
+ s = ""
+ } else {
+ id = s[:q]
+ s = s[q+1:]
+ }
+ n.Attr = append(n.Attr, Attribute{Key: key, Val: id})
+ if key == "public" {
+ key = "system"
+ } else {
+ key = ""
+ }
+ }
+
+ return n
+}
diff --git a/internal/parser.go b/internal/parser.go
index 42d7eb0d8..3dc5c737b 100644
--- a/internal/parser.go
+++ b/internal/parser.go
@@ -393,7 +393,6 @@ func (p *parser) addExpression() {
Loc: p.generateLoc(),
Namespace: p.top().Namespace,
})
-
}
func isFragment(data string) bool {
@@ -725,6 +724,38 @@ func beforeHTMLIM(p *parser) bool {
return false
}
+func initialIMExact(p *parser) bool {
+ switch p.tok.Type {
+ case FrontmatterFenceToken:
+ p.setOriginalIM()
+ p.im = frontmatterIM
+ return false
+ case TextToken:
+ p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)
+ if len(p.tok.Data) == 0 {
+ // It was all whitespace, so ignore it.
+ return true
+ }
+ case CommentToken:
+ p.doc.AppendChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ Loc: p.generateLoc(),
+ })
+ return true
+ case DoctypeToken:
+ n := parseDoctypeExact(p.tok.Data)
+ p.doc.AppendChild(n)
+ p.im = inLiteralIMExact
+ return true
+ }
+ if p.frontmatterState == FrontmatterInitial {
+ p.addFrontmatter(true)
+ }
+ p.im = inLiteralIMExact
+ return false
+}
+
// Section 12.2.6.4.3.
func beforeHeadIM(p *parser) bool {
switch p.tok.Type {
@@ -1776,6 +1807,14 @@ func textIM(p *parser) bool {
return p.tok.Type == EndTagToken
}
+func parseText(p *parser) {
+ d := p.tok.Data
+ if d == "" {
+ return
+ }
+ p.addText(d)
+}
+
// Section 12.2.6.4.9.
func inTableIM(p *parser) bool {
switch p.tok.Type {
@@ -2805,6 +2844,42 @@ func inExpressionIM(p *parser) bool {
return p.tok.Type == EndTagToken
}
+func inLiteralIMExact(p *parser) bool {
+ switch p.tok.Type {
+ case DoctypeToken:
+ n := parseDoctypeExact(p.tok.Data)
+ p.doc.AppendChild(n)
+ case StartTagToken:
+ p.addElement()
+ if p.hasSelfClosingToken {
+ p.addLoc()
+ p.oe.pop()
+ p.acknowledgeSelfClosingTag()
+ }
+ case StartExpressionToken:
+ p.addExpression()
+ p.setOriginalIM()
+ p.im = inExpressionIMExact
+ case ErrorToken:
+ // ignore the token
+ case TextToken:
+ parseText(p)
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ Loc: p.generateLoc(),
+ })
+ case EndTagToken:
+ p.addLoc()
+ p.oe.pop()
+ case EndExpressionToken:
+ p.addLoc()
+ p.oe.pop()
+ }
+ return true
+}
+
func ignoreTheRemainingTokens(p *parser) bool {
return true
}
@@ -2817,6 +2892,34 @@ func getExitLiteralFunc(p *parser) func() bool {
}
}
+func inExpressionIMExact(p *parser) bool {
+ switch p.tok.Type {
+ case ErrorToken:
+ p.oe.pop()
+ case TextToken:
+ parseText(p)
+ return true
+ case StartTagToken, EndTagToken:
+ return inLiteralIMExact(p)
+ case EndExpressionToken:
+ p.addLoc()
+ p.oe.pop()
+ p.im = p.originalIM
+ p.originalIM = nil
+ return true
+ case CommentToken:
+ p.addChild(&Node{
+ Type: CommentNode,
+ Data: p.tok.Data,
+ Loc: p.generateLoc(),
+ })
+ return true
+ }
+ p.im = p.originalIM
+ p.originalIM = nil
+ return p.tok.Type == EndTagToken
+}
+
const whitespaceOrNUL = whitespace + "\x00"
// Section 12.2.6.5
@@ -3052,6 +3155,14 @@ func ParseOptionEnableLiteral(enable bool) ParseOption {
}
}
+func ParseOptionExperimentalBetterLiteralThingy(enable bool) ParseOption {
+ return func(p *parser) {
+ if enable {
+ p.im = initialIMExact
+ }
+ }
+}
+
// ParseWithOptions is like Parse, with options.
func ParseWithOptions(r io.Reader, opts ...ParseOption) (*Node, error) {
p := &parser{
@@ -3060,8 +3171,10 @@ func ParseWithOptions(r io.Reader, opts ...ParseOption) (*Node, error) {
Type: DocumentNode,
HydrationDirectives: make(map[string]bool),
},
- framesetOK: true,
- im: initialIM,
+ framesetOK: true,
+ // TODO: use the experimental flag
+ // to choose the correct initial insertion mode
+ im: initialIMExact,
frontmatterState: FrontmatterInitial,
exitLiteralIM: func() bool { return false },
}
diff --git a/internal/transform/scope-css_test.go b/internal/transform/scope-css_test.go
index 9510b841b..087a15e72 100644
--- a/internal/transform/scope-css_test.go
+++ b/internal/transform/scope-css_test.go
@@ -6,6 +6,7 @@ import (
astro "github.com/withastro/compiler/internal"
"github.com/withastro/compiler/internal/test_utils"
+ "golang.org/x/net/html/atom"
)
func TestScopeStyle(t *testing.T) {
@@ -283,7 +284,13 @@ func TestScopeStyle(t *testing.T) {
if err != nil {
t.Error(err)
}
- styleEl := doc.LastChild.FirstChild.FirstChild // note: root is , and we need to get `)
@@ -586,7 +600,14 @@ func TestClassAndClassListMerging(t *testing.T) {
t.Error(err)
}
Transform(doc, TransformOptions{}, handler.NewHandler(tt.source, "/test.astro"))
- astro.PrintToSource(&b, doc.LastChild.FirstChild.NextSibling.FirstChild)
+
+ var node *astro.Node
+ walk(doc, func(n *astro.Node) {
+ if node == nil && n.Type == astro.ElementNode && n.DataAtom == atom.Div {
+ node = n
+ }
+ })
+ astro.PrintToSource(&b, node)
got := b.String()
if tt.want != got {
t.Errorf("\nFAIL: %s\n want: %s\n got: %s", tt.name, tt.want, got)
From f1689ea273aa815b70ab21371e139edc852491e9 Mon Sep 17 00:00:00 2001
From: Moustapha HappyDev
Date: Tue, 10 Jun 2025 16:04:53 +0000
Subject: [PATCH 04/13] feat: make exact HTML parsing an opt-in experimental
feature
This commit makes the previously implemented exact HTML parsing mode an opt-in experimental feature rather than the default parsing mode. The new implementation:
1. Adds an `experimentalExactParsingThingy` flag to control whether to use the more precise HTML parsing mode.
Will use a more formal name once we think it through
2. Reverts the default insertion mode from `initialIMExact` back to `initialIM`
3. Updates all WASM bindings to pass the experimental flag through to the parser
4. Adds extensive test coverage with duplicated previously failing test cases that verify the behavior with exact parsing enabled
The exact parsing mode preserves the original HTML document structure more faithfully, allowing invalid HTML to pass through to the browser rather than having the parser attempt to normalize it.
(Commit written with the assistance of AI)
---
cmd/astro-wasm/astro-wasm.go | 40 +-
internal/parser.go | 6 +-
...s_in_expressions_-_with_exact_parsing.snap | 41 ++
...ramework_example_-_with_exact_parsing.snap | 116 +++++
...ponent__default__-_with_exact_parsing.snap | 59 +++
...onent__multiple__-_with_exact_parsing.snap | 63 +++
...omponent__named__-_with_exact_parsing.snap | 59 +++
...nent__namespace__-_with_exact_parsing.snap | 59 +++
...espaced_default__-_with_exact_parsing.snap | 59 +++
...amespaced_named__-_with_exact_parsing.snap | 59 +++
.../component_-_with_exact_parsing.snap | 61 +++
.../dot_component__-_with_exact_parsing.snap | 61 +++
...iple_elements_-_with_verbatim_parsing.snap | 89 ++++
.../head_expression_-_with_exact_parsing.snap | 60 +++
...ring_of_fragment_-_with_exact_parsing.snap | 64 +++
...tml5_boilerplate_-_with_exact_parsing.snap | 99 ++++
.../import.meta.env_-_with_exact_parsing.snap | 131 +++++
...tays_in_the_head_-_with_exact_parsing.snap | 73 +++
...teral_expression_-_with_exact_parsing.snap | 51 ++
...script_component_-_with_exact_parsing.snap | 55 ++
...able_simple_case_-_with_exact_parsing.snap | 77 +++
...th_an_expression_-_with_exact_parsing.snap | 42 ++
...th_an_expression_-_with_exact_parsing.snap | 42 ++
...template_literal_-_with_exact_parsing.snap | 42 ++
...a_data_attribute_-_with_exact_parsing.snap | 42 ++
...a_data_attribute_-_with_exact_parsing.snap | 42 ++
..._name_if_defined_-_with_exact_parsing.snap | 42 ++
internal/printer/printer_test.go | 483 +++++++++++++++++-
internal/transform/transform.go | 1 +
internal/transform/transform_test.go | 22 +-
packages/compiler/src/shared/types.ts | 4 +-
31 files changed, 2116 insertions(+), 28 deletions(-)
create mode 100755 internal/printer/__printer_js__/Preserve_namespaces_in_expressions_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/React_framework_example_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/client_only_component__default__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/client_only_component__multiple__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/client_only_component__named__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/client_only_component__namespace__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/client_only_component__namespaced_default__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/client_only_component__namespaced_named__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/component_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/dot_component__-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/expression_returning_multiple_elements_-_with_verbatim_parsing.snap
create mode 100755 internal/printer/__printer_js__/head_expression_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/head_expression_and_conditional_rendering_of_fragment_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/html5_boilerplate_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/import.meta.env_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/nested_head_content_stays_in_the_head_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/nested_template_literal_expression_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/noscript_component_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/table_simple_case_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/transition_animate_with_an_expression_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/transition_name_with_an_expression_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/transition_name_with_an_template_literal_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/transition_persist-props_converted_to_a_data_attribute_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/transition_persist_converted_to_a_data_attribute_-_with_exact_parsing.snap
create mode 100755 internal/printer/__printer_js__/transition_persist_uses_transition_name_if_defined_-_with_exact_parsing.snap
diff --git a/cmd/astro-wasm/astro-wasm.go b/cmd/astro-wasm/astro-wasm.go
index 3dfdba839..a36102898 100644
--- a/cmd/astro-wasm/astro-wasm.go
+++ b/cmd/astro-wasm/astro-wasm.go
@@ -143,21 +143,27 @@ func makeTransformOptions(options js.Value) transform.TransformOptions {
experimentalScriptOrder = true
}
+ experimentalExactParsingThingy := false
+ if jsBool(options.Get("experimentalExactParsingThingy")) {
+ experimentalExactParsingThingy = true
+ }
+
return transform.TransformOptions{
- Filename: filename,
- NormalizedFilename: normalizedFilename,
- InternalURL: internalURL,
- SourceMap: sourcemap,
- AstroGlobalArgs: astroGlobalArgs,
- Compact: compact,
- ResolvePath: resolvePathFn,
- PreprocessStyle: preprocessStyle,
- ResultScopedSlot: scopedSlot,
- ScopedStyleStrategy: scopedStyleStrategy,
- TransitionsAnimationURL: transitionsAnimationURL,
- AnnotateSourceFile: annotateSourceFile,
- RenderScript: renderScript,
- ExperimentalScriptOrder: experimentalScriptOrder,
+ Filename: filename,
+ NormalizedFilename: normalizedFilename,
+ InternalURL: internalURL,
+ SourceMap: sourcemap,
+ AstroGlobalArgs: astroGlobalArgs,
+ Compact: compact,
+ ResolvePath: resolvePathFn,
+ PreprocessStyle: preprocessStyle,
+ ResultScopedSlot: scopedSlot,
+ ScopedStyleStrategy: scopedStyleStrategy,
+ TransitionsAnimationURL: transitionsAnimationURL,
+ AnnotateSourceFile: annotateSourceFile,
+ RenderScript: renderScript,
+ ExperimentalScriptOrder: experimentalScriptOrder,
+ ExperimentalExactParsingThingy: experimentalExactParsingThingy,
}
}
@@ -257,7 +263,7 @@ func Parse() any {
h := handler.NewHandler(source, parseOptions.Filename)
var doc *astro.Node
- doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))
+ doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true), astro.ParseOptionExperimentalBetterLiteralThingy(transformOptions.ExperimentalExactParsingThingy))
if err != nil {
h.AppendError(err)
}
@@ -281,7 +287,7 @@ func ConvertToTSX() any {
h := handler.NewHandler(source, transformOptions.Filename)
var doc *astro.Node
- doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))
+ doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true), astro.ParseOptionExperimentalBetterLiteralThingy(transformOptions.ExperimentalExactParsingThingy))
if err != nil {
h.AppendError(err)
}
@@ -335,7 +341,7 @@ func Transform() any {
}
}()
- doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h))
+ doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true), astro.ParseOptionExperimentalBetterLiteralThingy(transformOptions.ExperimentalExactParsingThingy))
if err != nil {
reject.Invoke(wasm_utils.ErrorToJSError(h, err))
return
diff --git a/internal/parser.go b/internal/parser.go
index 3dc5c737b..352aff166 100644
--- a/internal/parser.go
+++ b/internal/parser.go
@@ -3171,10 +3171,8 @@ func ParseWithOptions(r io.Reader, opts ...ParseOption) (*Node, error) {
Type: DocumentNode,
HydrationDirectives: make(map[string]bool),
},
- framesetOK: true,
- // TODO: use the experimental flag
- // to choose the correct initial insertion mode
- im: initialIMExact,
+ framesetOK: true,
+ im: initialIM,
frontmatterState: FrontmatterInitial,
exitLiteralIM: func() bool { return false },
}
diff --git a/internal/printer/__printer_js__/Preserve_namespaces_in_expressions_-_with_exact_parsing.snap b/internal/printer/__printer_js__/Preserve_namespaces_in_expressions_-_with_exact_parsing.snap
new file mode 100755
index 000000000..3205c24fd
--- /dev/null
+++ b/internal/printer/__printer_js__/Preserve_namespaces_in_expressions_-_with_exact_parsing.snap
@@ -0,0 +1,41 @@
+
+[TestPrinter/Preserve_namespaces_in_expressions_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/React_framework_example_-_with_exact_parsing.snap b/internal/printer/__printer_js__/React_framework_example_-_with_exact_parsing.snap
new file mode 100755
index 000000000..39fe3881d
--- /dev/null
+++ b/internal/printer/__printer_js__/React_framework_example_-_with_exact_parsing.snap
@@ -0,0 +1,116 @@
+
+[TestPrinter/React_framework_example_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+// Component Imports
+import Counter from '../components/Counter.jsx'
+const someProps = {
+ count: 0,
+}
+
+// Full Astro Component Syntax:
+// https://docs.astro.build/core-concepts/astro-components/
+/-/-/-/
+
+
+
+
+
+
+
+
+
+
+ Hello React!
+
+
+
+
+```
+
+## 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/";
+import Counter from '../components/Counter.jsx'
+
+
+import * as $$module1 from '../components/Counter.jsx';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/Counter.jsx', assert: {} }], hydratedComponents: [Counter], clientOnlyComponents: [], hydrationDirectives: new Set(['visible']), hoisted: [] });
+
+const $$Astro = $$createAstro('https://astro.build');
+const Astro = $$Astro;
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+const Astro = $$result.createAstro($$Astro, $$props, $$slots);
+Astro.self = $$Component;
+
+// Component Imports
+
+const someProps = {
+ count: 0,
+}
+
+// Full Astro Component Syntax:
+// https://docs.astro.build/core-concepts/astro-components/
+
+return $$render`
+
+
+
+
+
+ ${$$renderHead($$result)}
+
+
+ ${$$renderComponent($$result,'Counter',Counter,{...(someProps),"client:visible":true,"client:component-hydration":"visible","client:component-path":("../components/Counter.jsx"),"client:component-export":("default"),"class":"astro-hmnnhvcq"},{"default": () => $$render`
+ Hello React!
+ `,})}
+
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/client_only_component__default__-_with_exact_parsing.snap b/internal/printer/__printer_js__/client_only_component__default__-_with_exact_parsing.snap
new file mode 100755
index 000000000..0db0091fd
--- /dev/null
+++ b/internal/printer/__printer_js__/client_only_component__default__-_with_exact_parsing.snap
@@ -0,0 +1,59 @@
+
+[TestPrinter/client:only_component_(default)_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import Component from '../components';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import Component from '../components';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'Component',null,{"client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components")),"client:component-export":"default"})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/client_only_component__multiple__-_with_exact_parsing.snap b/internal/printer/__printer_js__/client_only_component__multiple__-_with_exact_parsing.snap
new file mode 100755
index 000000000..2fc23069c
--- /dev/null
+++ b/internal/printer/__printer_js__/client_only_component__multiple__-_with_exact_parsing.snap
@@ -0,0 +1,63 @@
+
+[TestPrinter/client:only_component_(multiple)_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import Component from '../components';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+
+
+```
+
+## 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/";
+import Component from '../components';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'Component',null,{"test":"a","client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components")),"client:component-export":"default"})}
+ ${$$renderComponent($$result,'Component',null,{"test":"b","client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components")),"client:component-export":"default"})}
+ ${$$renderComponent($$result,'Component',null,{"test":"c","client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components")),"client:component-export":"default"})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/client_only_component__named__-_with_exact_parsing.snap b/internal/printer/__printer_js__/client_only_component__named__-_with_exact_parsing.snap
new file mode 100755
index 000000000..693ad7864
--- /dev/null
+++ b/internal/printer/__printer_js__/client_only_component__named__-_with_exact_parsing.snap
@@ -0,0 +1,59 @@
+
+[TestPrinter/client:only_component_(named)_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import { Component } from '../components';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import { Component } from '../components';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'Component',null,{"client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components")),"client:component-export":"Component"})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/client_only_component__namespace__-_with_exact_parsing.snap b/internal/printer/__printer_js__/client_only_component__namespace__-_with_exact_parsing.snap
new file mode 100755
index 000000000..c1079b885
--- /dev/null
+++ b/internal/printer/__printer_js__/client_only_component__namespace__-_with_exact_parsing.snap
@@ -0,0 +1,59 @@
+
+[TestPrinter/client:only_component_(namespace)_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import * as components from '../components';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import * as components from '../components';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'components.A',null,{"client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components")),"client:component-export":"A"})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/client_only_component__namespaced_default__-_with_exact_parsing.snap b/internal/printer/__printer_js__/client_only_component__namespaced_default__-_with_exact_parsing.snap
new file mode 100755
index 000000000..bb101a5fd
--- /dev/null
+++ b/internal/printer/__printer_js__/client_only_component__namespaced_default__-_with_exact_parsing.snap
@@ -0,0 +1,59 @@
+
+[TestPrinter/client:only_component_(namespaced_default)_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import defaultImport from '../components/ui-1';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import defaultImport from '../components/ui-1';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components/ui-1'], hydrationDirectives: new Set(['only']), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'defaultImport.Counter1',null,{"client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components/ui-1")),"client:component-export":"default.Counter1"})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/client_only_component__namespaced_named__-_with_exact_parsing.snap b/internal/printer/__printer_js__/client_only_component__namespaced_named__-_with_exact_parsing.snap
new file mode 100755
index 000000000..d1cf91a1b
--- /dev/null
+++ b/internal/printer/__printer_js__/client_only_component__namespaced_named__-_with_exact_parsing.snap
@@ -0,0 +1,59 @@
+
+[TestPrinter/client:only_component_(namespaced_named)_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import { namedImport } from '../components/ui-2';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import { namedImport } from '../components/ui-2';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components/ui-2'], hydrationDirectives: new Set(['only']), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'namedImport.Counter2',null,{"client:only":true,"client:component-hydration":"only","client:component-path":($$metadata.resolvePath("../components/ui-2")),"client:component-export":"namedImport.Counter2"})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/component_-_with_exact_parsing.snap b/internal/printer/__printer_js__/component_-_with_exact_parsing.snap
new file mode 100755
index 000000000..77fa56a71
--- /dev/null
+++ b/internal/printer/__printer_js__/component_-_with_exact_parsing.snap
@@ -0,0 +1,61 @@
+
+[TestPrinter/component_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import VueComponent from '../components/Vue.vue';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import VueComponent from '../components/Vue.vue';
+
+import * as $$module1 from '../components/Vue.vue';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/Vue.vue', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'VueComponent',VueComponent,{})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/dot_component__-_with_exact_parsing.snap b/internal/printer/__printer_js__/dot_component__-_with_exact_parsing.snap
new file mode 100755
index 000000000..265872db8
--- /dev/null
+++ b/internal/printer/__printer_js__/dot_component__-_with_exact_parsing.snap
@@ -0,0 +1,61 @@
+
+[TestPrinter/dot_component__-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import * as ns from '../components';
+/-/-/-/
+
+
+ Hello world
+
+
+
+
+
+```
+
+## 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/";
+import * as ns from '../components';
+
+import * as $$module1 from '../components';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+ Hello world
+ ${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'ns.Component',ns.Component,{})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/expression_returning_multiple_elements_-_with_verbatim_parsing.snap b/internal/printer/__printer_js__/expression_returning_multiple_elements_-_with_verbatim_parsing.snap
new file mode 100755
index 000000000..452905f22
--- /dev/null
+++ b/internal/printer/__printer_js__/expression_returning_multiple_elements_-_with_verbatim_parsing.snap
@@ -0,0 +1,89 @@
+
+[TestPrinter/expression_returning_multiple_elements_-_with_verbatim_parsing - 1]
+## Input
+
+```
+
+
+ Welcome to Astro
+ {
+ Object.entries(DUMMY_DATA).map(([dummyKey, dummyValue]) => {
+ return (
+
+ onlyp {dummyKey}
+
+
+ onlyh2 {dummyKey}
+
+
+
div+h2 {dummyKey}
+
+
+
p+h2 {dummyKey}
+
+ );
+ })
+ }
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Astro = $$createAstro('https://astro.build');
+const Astro = $$Astro;
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+const Astro = $$result.createAstro($$Astro, $$props, $$slots);
+Astro.self = $$Component;
+
+return $$render`${$$renderComponent($$result,'Layout',Layout,{"title":"Welcome to Astro."},{"default": () => $$render`
+ ${$$maybeRenderHead($$result)}
+ Welcome to Astro
+ ${
+ Object.entries(DUMMY_DATA).map(([dummyKey, dummyValue]) => {
+ return (
+ $$render`
+ onlyp ${dummyKey}
+
+
+ onlyh2 ${dummyKey}
+
+
+
div+h2 ${dummyKey}
+
+
+
p+h2 ${dummyKey}
+ `
+ );
+ })
+ }
+
+`,})}`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/head_expression_-_with_exact_parsing.snap b/internal/printer/__printer_js__/head_expression_-_with_exact_parsing.snap
new file mode 100755
index 000000000..d12289e27
--- /dev/null
+++ b/internal/printer/__printer_js__/head_expression_-_with_exact_parsing.snap
@@ -0,0 +1,60 @@
+
+[TestPrinter/head_expression_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+const name = "world";
+/-/-/-/
+
+
+ Hello {name}
+
+
+
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+const name = "world";
+
+return $$render`
+
+ Hello ${name}
+ ${$$renderHead($$result)}
+
+
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/head_expression_and_conditional_rendering_of_fragment_-_with_exact_parsing.snap b/internal/printer/__printer_js__/head_expression_and_conditional_rendering_of_fragment_-_with_exact_parsing.snap
new file mode 100755
index 000000000..b5560bf7d
--- /dev/null
+++ b/internal/printer/__printer_js__/head_expression_and_conditional_rendering_of_fragment_-_with_exact_parsing.snap
@@ -0,0 +1,64 @@
+
+[TestPrinter/head_expression_and_conditional_rendering_of_fragment_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+const testBool = true;
+/-/-/-/
+
+
+
+ {testBool ? "Hey" : "Bye"}
+ {testBool && (<>>)}
+
+
+
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+const testBool = true;
+
+return $$render`
+
+
+ ${testBool ? "Hey" : "Bye"}
+ ${testBool && ($$render`${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render``,})}`)}
+ ${$$renderHead($$result)}
+
+
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/html5_boilerplate_-_with_exact_parsing.snap b/internal/printer/__printer_js__/html5_boilerplate_-_with_exact_parsing.snap
new file mode 100755
index 000000000..ec614654f
--- /dev/null
+++ b/internal/printer/__printer_js__/html5_boilerplate_-_with_exact_parsing.snap
@@ -0,0 +1,99 @@
+
+[TestPrinter/html5_boilerplate_-_with_exact_parsing - 1]
+## Input
+
+```
+
+
+
+
+
+
+
+ A Basic HTML5 Template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+
+
+
+
+
+
+ A Basic HTML5 Template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+${$$renderHead($$result)}
+
+
+
+
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/import.meta.env_-_with_exact_parsing.snap b/internal/printer/__printer_js__/import.meta.env_-_with_exact_parsing.snap
new file mode 100755
index 000000000..97f0026f2
--- /dev/null
+++ b/internal/printer/__printer_js__/import.meta.env_-_with_exact_parsing.snap
@@ -0,0 +1,131 @@
+
+[TestPrinter/import.meta.env_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+import Header from '../../components/Header.jsx'
+import Footer from '../../components/Footer.astro'
+import ProductPageContent from '../../components/ProductPageContent.jsx';
+
+export async function getStaticPaths() {
+ let products = await fetch(`${import.meta.env.PUBLIC_NETLIFY_URL}/.netlify/functions/get-product-list`)
+ .then(res => res.json()).then((response) => {
+ console.log('--- built product pages ---')
+ return response.products.edges
+ });
+
+ return products.map((p, i) => {
+ return {
+ params: {pid: p.node.handle},
+ props: {product: p},
+ };
+ });
+}
+
+const { product } = Astro.props;
+/-/-/-/
+
+
+
+
+
+
+ Shoperoni | Buy {product.node.title}
+
+
+
+
+
+
+
+
+
+
+```
+
+## 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/";
+import Header from '../../components/Header.jsx'
+
+import Footer from '../../components/Footer.astro'
+
+import ProductPageContent from '../../components/ProductPageContent.jsx';
+
+import * as $$module1 from '../../components/Header.jsx';
+import * as $$module2 from '../../components/Footer.astro';
+import * as $$module3 from '../../components/ProductPageContent.jsx';
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../../components/Header.jsx', assert: {} }, { module: $$module2, specifier: '../../components/Footer.astro', assert: {} }, { module: $$module3, specifier: '../../components/ProductPageContent.jsx', assert: {} }], hydratedComponents: [ProductPageContent], clientOnlyComponents: [], hydrationDirectives: new Set(['visible']), hoisted: [] });
+
+const $$Astro = $$createAstro('https://astro.build');
+const Astro = $$Astro;
+export async function getStaticPaths() {
+ let products = await fetch(`${import.meta.env.PUBLIC_NETLIFY_URL}/.netlify/functions/get-product-list`)
+ .then(res => res.json()).then((response) => {
+ console.log('--- built product pages ---')
+ return response.products.edges
+ });
+
+ return products.map((p, i) => {
+ return {
+ params: {pid: p.node.handle},
+ props: {product: p},
+ };
+ });
+}
+const $$Component = $$createComponent(async ($$result, $$props, $$slots) => {
+const Astro = $$result.createAstro($$Astro, $$props, $$slots);
+Astro.self = $$Component;
+
+const { product } = Astro.props;
+
+return $$render`
+
+
+
+
+ Shoperoni | Buy ${product.node.title}
+
+
+
+${$$renderHead($$result)}
+
+ ${$$renderComponent($$result,'Header',Header,{})}
+
+
+ ${$$renderComponent($$result,'ProductPageContent',ProductPageContent,{"client:visible":true,"product":(product.node),"client:component-hydration":"visible","client:component-path":("../../components/ProductPageContent.jsx"),"client:component-export":("default")})}
+
+
+ ${$$renderComponent($$result,'Footer',Footer,{})}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/nested_head_content_stays_in_the_head_-_with_exact_parsing.snap b/internal/printer/__printer_js__/nested_head_content_stays_in_the_head_-_with_exact_parsing.snap
new file mode 100755
index 000000000..68c0de152
--- /dev/null
+++ b/internal/printer/__printer_js__/nested_head_content_stays_in_the_head_-_with_exact_parsing.snap
@@ -0,0 +1,73 @@
+
+[TestPrinter/nested_head_content_stays_in_the_head_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+const meta = { title: 'My App' };
+/-/-/-/
+
+
+
+
+
+ {
+ meta && {meta.title}
+ }
+
+
+
+
+ My App
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+const meta = { title: 'My App' };
+
+return $$render`
+
+
+
+ ${
+ meta && $$render`${meta.title}`
+ }
+
+
+ ${$$renderHead($$result)}
+
+ My App
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/nested_template_literal_expression_-_with_exact_parsing.snap b/internal/printer/__printer_js__/nested_template_literal_expression_-_with_exact_parsing.snap
new file mode 100755
index 000000000..f0f877b13
--- /dev/null
+++ b/internal/printer/__printer_js__/nested_template_literal_expression_-_with_exact_parsing.snap
@@ -0,0 +1,51 @@
+
+[TestPrinter/nested_template_literal_expression_-_with_exact_parsing - 1]
+## Input
+
+```
+
+
+{Object.keys(importedAuthors).map(author => hello
)}
+{Object.keys(importedAuthors).map(author => {author}
)}
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+${$$maybeRenderHead($$result)}
+${Object.keys(importedAuthors).map(author => $$render`hello
`)}
+${Object.keys(importedAuthors).map(author => $$render`${author}
`)}
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/noscript_component_-_with_exact_parsing.snap b/internal/printer/__printer_js__/noscript_component_-_with_exact_parsing.snap
new file mode 100755
index 000000000..5375b9366
--- /dev/null
+++ b/internal/printer/__printer_js__/noscript_component_-_with_exact_parsing.snap
@@ -0,0 +1,55 @@
+
+[TestPrinter/noscript_component_-_with_exact_parsing - 1]
+## Input
+
+```
+
+
+
+
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`
+ ${$$renderHead($$result)}
+
+
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/table_simple_case_-_with_exact_parsing.snap b/internal/printer/__printer_js__/table_simple_case_-_with_exact_parsing.snap
new file mode 100755
index 000000000..22fab06da
--- /dev/null
+++ b/internal/printer/__printer_js__/table_simple_case_-_with_exact_parsing.snap
@@ -0,0 +1,77 @@
+
+[TestPrinter/table_simple_case_-_with_exact_parsing - 1]
+## Input
+
+```
+/-/-/-/
+const content = "lol";
+/-/-/-/
+
+
+
+
+
+ {content} |
+
+ {
+ (
+
+ 1 |
+
+ )
+ }
+
Hello
+
+
+```
+
+## 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(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+const content = "lol";
+
+return $$render`
+ ${$$maybeRenderHead($$result)}
+
+
+ ${content} |
+
+ ${
+ (
+ $$render`
+ 1 |
+
`
+ )
+ }
+
Hello
+
+`;
+}, undefined, undefined);
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/transition_animate_with_an_expression_-_with_exact_parsing.snap b/internal/printer/__printer_js__/transition_animate_with_an_expression_-_with_exact_parsing.snap
new file mode 100755
index 000000000..10fd6e1f4
--- /dev/null
+++ b/internal/printer/__printer_js__/transition_animate_with_an_expression_-_with_exact_parsing.snap
@@ -0,0 +1,42 @@
+
+[TestPrinter/transition:animate_with_an_expression_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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/";
+import "transitions.css";
+
+export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Page = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, '/projects/app/src/pages/page.astro', 'self');
+export default $$Page;
+```
+---
diff --git a/internal/printer/__printer_js__/transition_name_with_an_expression_-_with_exact_parsing.snap b/internal/printer/__printer_js__/transition_name_with_an_expression_-_with_exact_parsing.snap
new file mode 100755
index 000000000..f1f5977f3
--- /dev/null
+++ b/internal/printer/__printer_js__/transition_name_with_an_expression_-_with_exact_parsing.snap
@@ -0,0 +1,42 @@
+
+[TestPrinter/transition:name_with_an_expression_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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/";
+import "transitions.css";
+
+export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Page = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, '/projects/app/src/pages/page.astro', 'self');
+export default $$Page;
+```
+---
diff --git a/internal/printer/__printer_js__/transition_name_with_an_template_literal_-_with_exact_parsing.snap b/internal/printer/__printer_js__/transition_name_with_an_template_literal_-_with_exact_parsing.snap
new file mode 100755
index 000000000..d65a43eac
--- /dev/null
+++ b/internal/printer/__printer_js__/transition_name_with_an_template_literal_-_with_exact_parsing.snap
@@ -0,0 +1,42 @@
+
+[TestPrinter/transition:name_with_an_template_literal_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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/";
+import "transitions.css";
+
+export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Page = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, '/projects/app/src/pages/page.astro', 'self');
+export default $$Page;
+```
+---
diff --git a/internal/printer/__printer_js__/transition_persist-props_converted_to_a_data_attribute_-_with_exact_parsing.snap b/internal/printer/__printer_js__/transition_persist-props_converted_to_a_data_attribute_-_with_exact_parsing.snap
new file mode 100755
index 000000000..5e459e52c
--- /dev/null
+++ b/internal/printer/__printer_js__/transition_persist-props_converted_to_a_data_attribute_-_with_exact_parsing.snap
@@ -0,0 +1,42 @@
+
+[TestPrinter/transition:persist-props_converted_to_a_data_attribute_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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/";
+import "transitions.css";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$renderComponent($$result,'my-island','my-island',{"data-astro-transition-persist-props":"false","data-astro-transition-persist":($$createTransitionScope($$result, "oh2whuuc"))})}`;
+}, undefined, 'self');
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/transition_persist_converted_to_a_data_attribute_-_with_exact_parsing.snap b/internal/printer/__printer_js__/transition_persist_converted_to_a_data_attribute_-_with_exact_parsing.snap
new file mode 100755
index 000000000..dd9275e11
--- /dev/null
+++ b/internal/printer/__printer_js__/transition_persist_converted_to_a_data_attribute_-_with_exact_parsing.snap
@@ -0,0 +1,42 @@
+
+[TestPrinter/transition:persist_converted_to_a_data_attribute_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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/";
+import "transitions.css";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, undefined, 'self');
+export default $$Component;
+```
+---
diff --git a/internal/printer/__printer_js__/transition_persist_uses_transition_name_if_defined_-_with_exact_parsing.snap b/internal/printer/__printer_js__/transition_persist_uses_transition_name_if_defined_-_with_exact_parsing.snap
new file mode 100755
index 000000000..8d44f6eb3
--- /dev/null
+++ b/internal/printer/__printer_js__/transition_persist_uses_transition_name_if_defined_-_with_exact_parsing.snap
@@ -0,0 +1,42 @@
+
+[TestPrinter/transition:persist_uses_transition:name_if_defined_-_with_exact_parsing - 1]
+## Input
+
+```
+
+```
+
+## 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/";
+import "transitions.css";
+
+export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
+
+const $$Component = $$createComponent(($$result, $$props, $$slots) => {
+
+return $$render`${$$maybeRenderHead($$result)}`;
+}, undefined, 'self');
+export default $$Component;
+```
+---
diff --git a/internal/printer/printer_test.go b/internal/printer/printer_test.go
index 530921330..9bd4cb533 100644
--- a/internal/printer/printer_test.go
+++ b/internal/printer/printer_test.go
@@ -368,6 +368,35 @@ import type data from "test"
`,
},
+ {
+ name: "expression returning multiple elements - with verbatim parsing",
+ source: `
+
+ Welcome to Astro
+ {
+ Object.entries(DUMMY_DATA).map(([dummyKey, dummyValue]) => {
+ return (
+
+ onlyp {dummyKey}
+
+
+ onlyh2 {dummyKey}
+
+
+
div+h2 {dummyKey}
+
+
+
p+h2 {dummyKey}
+
+ );
+ })
+ }
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "nested template literal expression",
source: `
@@ -377,6 +406,18 @@ import type data from "test"
`,
},
+ {
+ name: "nested template literal expression - with exact parsing",
+ source: `
+
+{Object.keys(importedAuthors).map(author => hello
)}
+{Object.keys(importedAuthors).map(author => {author}
)}
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "complex nested template literal expression",
source: "",
@@ -395,6 +436,23 @@ import VueComponent from '../components/Vue.vue';
`,
},
+ {
+ name: "component - with exact parsing",
+ source: `---
+import VueComponent from '../components/Vue.vue';
+---
+
+
+ Hello world
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "dot component",
source: `---
@@ -409,6 +467,23 @@ import * as ns from '../components';
`,
},
+ {
+ name: "dot component - with exact parsing",
+ source: `---
+import * as ns from '../components';
+---
+
+
+ Hello world
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "component with quoted attributes",
source: ``,
@@ -437,6 +512,21 @@ import * as ns from '../components';
`,
},
+ {
+ name: "noscript component - with exact parsing",
+ source: `
+
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "noscript styles",
source: ``,
@@ -463,6 +553,23 @@ import Component from '../components';
`,
},
+ {
+ name: "client:only component (default) - with exact parsing",
+ source: `---
+import Component from '../components';
+---
+
+
+ Hello world
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "client:only component (named)",
source: `---
@@ -477,6 +584,23 @@ import { Component } from '../components';
`,
},
+ {
+ name: "client:only component (named) - with exact parsing",
+ source: `---
+import { Component } from '../components';
+---
+
+
+ Hello world
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "client:only component (namespace)",
source: `---
@@ -491,6 +615,23 @@ import * as components from '../components';
`,
},
+ {
+ name: "client:only component (namespace) - with exact parsing",
+ source: `---
+import * as components from '../components';
+---
+
+
+ Hello world
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "client:only component (namespaced default)",
source: `---
@@ -505,6 +646,23 @@ import defaultImport from '../components/ui-1';
`,
},
+ {
+ name: "client:only component (namespaced default) - with exact parsing",
+ source: `---
+import defaultImport from '../components/ui-1';
+---
+
+
+ Hello world
+
+
+
+
+`,
+ transformOptions: transform.TransformOptions{
+ ExperimentalExactParsingThingy: true,
+ },
+ },
{
name: "client:only component (namespaced named)",
source: `---
@@ -519,6 +677,23 @@ import { namedImport } from '../components/ui-2';