Skip to content

Commit 702e848

Browse files
virchau13Nate Moorenatemoo-re
authored
fix: strip newlines at the end of component files (#406)
* fix: strip newlines at the end of component files * refactor: trim trailing space in transform * test: add explicit space preservation test * Update chilly-chairs-enjoy.md Co-authored-by: Nate Moore <[email protected]> Co-authored-by: Nate Moore <[email protected]>
1 parent 3a1a24b commit 702e848

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

.changeset/chilly-chairs-enjoy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@astrojs/compiler': minor
3+
---
4+
5+
Trailing space at the end of Astro files is now stripped from Component output.

internal/transform/transform.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package transform
33
import (
44
"fmt"
55
"strings"
6+
"unicode"
67

78
astro "github.com/withastro/compiler/internal"
89
"github.com/withastro/compiler/internal/loc"
@@ -51,6 +52,8 @@ func Transform(doc *astro.Node, opts TransformOptions) *astro.Node {
5152
doc.AppendChild(empty)
5253
}
5354

55+
TrimTrailingSpace(doc)
56+
5457
return doc
5558
}
5659

@@ -126,6 +129,33 @@ func NormalizeSetDirectives(doc *astro.Node) {
126129
}
127130
}
128131

132+
func TrimTrailingSpace(doc *astro.Node) {
133+
if doc.LastChild == nil {
134+
return
135+
}
136+
137+
if doc.LastChild.Type == astro.TextNode {
138+
doc.LastChild.Data = strings.TrimRightFunc(doc.LastChild.Data, unicode.IsSpace)
139+
return
140+
}
141+
142+
n := doc.LastChild
143+
for i := 0; i < 2; i++ {
144+
// Loop through implicit nodes to find final trailing text node (html > body > #text)
145+
if n != nil && n.Type == astro.ElementNode && IsImplictNode(n) {
146+
n = n.LastChild
147+
continue
148+
} else {
149+
n = nil
150+
break
151+
}
152+
}
153+
154+
if n != nil && n.Type == astro.TextNode {
155+
n.Data = strings.TrimRightFunc(n.Data, unicode.IsSpace)
156+
}
157+
}
158+
129159
// TODO: cleanup sibling whitespace after removing scripts/styles
130160
// func removeSiblingWhitespace(n *astro.Node) {
131161
// if c := n.NextSibling; c != nil && c.Type == astro.TextNode {

internal/transform/transform_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,51 @@ func TestFullTransform(t *testing.T) {
198198
})
199199
}
200200
}
201+
202+
func TestTransformTrailingSpace(t *testing.T) {
203+
tests := []struct {
204+
name string
205+
source string
206+
want string
207+
}{
208+
{
209+
name: "component with trailing space",
210+
source: "<h1>Hello world</h1>\n\n\t ",
211+
want: `<h1>Hello world</h1>`,
212+
},
213+
{
214+
name: "component with no trailing space",
215+
source: "<h1>Hello world</h1>",
216+
want: "<h1>Hello world</h1>",
217+
},
218+
{
219+
name: "component with leading and trailing space",
220+
source: "<span/>\n\n\t <h1>Hello world</h1>\n\n\t ",
221+
want: "<span></span>\n\n\t <h1>Hello world</h1>",
222+
},
223+
{
224+
name: "html with explicit space",
225+
source: "<html><body>\n\n\n</body></html>",
226+
want: "<html><body>\n\n\n</body></html>",
227+
},
228+
}
229+
var b strings.Builder
230+
for _, tt := range tests {
231+
t.Run(tt.name, func(t *testing.T) {
232+
b.Reset()
233+
doc, err := astro.Parse(strings.NewReader(tt.source))
234+
if err != nil {
235+
t.Error(err)
236+
}
237+
ExtractStyles(doc)
238+
// Clear doc.Styles to avoid scoping behavior, we're not testing that here
239+
doc.Styles = make([]*astro.Node, 0)
240+
Transform(doc, TransformOptions{})
241+
astro.PrintToSource(&b, doc)
242+
got := b.String()
243+
if tt.want != got {
244+
t.Errorf("\nFAIL: %s\n want: %s\n got: %s", tt.name, tt.want, got)
245+
}
246+
})
247+
}
248+
}

packages/compiler/deno/astro.wasm

3.69 KB
Binary file not shown.

0 commit comments

Comments
 (0)