From 1ac2d630c73f3fbb35e067b74c755a61c85d9481 Mon Sep 17 00:00:00 2001 From: maddalax Date: Fri, 27 Sep 2024 16:18:09 -0500 Subject: [PATCH] dont close void tags --- framework/h/render_test.go | 18 ++++++++++++ framework/h/renderer.go | 56 ++++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/framework/h/render_test.go b/framework/h/render_test.go index 77325ae..12464fe 100644 --- a/framework/h/render_test.go +++ b/framework/h/render_test.go @@ -105,6 +105,24 @@ func TestConditional(t *testing.T) { assert.Equal(t, "
", result) } +func TestTagSelfClosing(t *testing.T) { + t.Parallel() + assert.Equal(t, ``, Render( + Input("text"), + )) + // assert the tag cannot have children + assert.Equal(t, ``, Render( + Input("text", Div()), + )) + + assert.Equal(t, `
`, Render( + Div(Id("test")), + )) + assert.Equal(t, `
`, Render( + Div(Id("test"), Div()), + )) +} + func BenchmarkMailToStatic(b *testing.B) { b.ReportAllocs() ctx := RenderContext{ diff --git a/framework/h/renderer.go b/framework/h/renderer.go index 16aef15..9f245c9 100644 --- a/framework/h/renderer.go +++ b/framework/h/renderer.go @@ -7,6 +7,26 @@ import ( "strings" ) +/* +* +void tags are tags that cannot have children +*/ +var voidTags = map[string]bool{ + "area": true, + "base": true, + "br": true, + "col": true, + "embed": true, + "hr": true, + "img": true, + "input": true, + "link": true, + "meta": true, + "source": true, + "track": true, + "wbr": true, +} + type RenderContext struct { builder *strings.Builder scripts []string @@ -79,28 +99,36 @@ func (node *Element) Render(context *RenderContext) { // close the tag if node.tag != "" { + if voidTags[node.tag] { + context.builder.WriteString("/") + } context.builder.WriteString(">") } - // render the children elements that are not attributes - for _, child := range node.children { - switch child.(type) { - case *AttributeMap: - continue - case *AttributeR: - continue - case *LifeCycle: - continue - default: - child.Render(context) + // void elements do not have children + if !voidTags[node.tag] { + // render the children elements that are not attributes + for _, child := range node.children { + switch child.(type) { + case *AttributeMap: + continue + case *AttributeR: + continue + case *LifeCycle: + continue + default: + child.Render(context) + } } } if node.tag != "" { renderScripts(context) - context.builder.WriteString("") + if !voidTags[node.tag] { + context.builder.WriteString("") + } } }