Skip to content

Commit 1aa0bcd

Browse files
virchau13Nate Moorenatemoo-re
committed
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 020e7d9 commit 1aa0bcd

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"
@@ -50,6 +51,8 @@ func Transform(doc *astro.Node, opts TransformOptions) *astro.Node {
5051
doc.AppendChild(empty)
5152
}
5253

54+
TrimTrailingSpace(doc)
55+
5356
return doc
5457
}
5558

@@ -125,6 +128,33 @@ func NormalizeSetDirectives(doc *astro.Node) {
125128
}
126129
}
127130

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