Skip to content

Commit 87c4872

Browse files
committed
introduced RenderWithOptions method, changed RenderTo signature; modified styles.CSS testing
1 parent 72ae017 commit 87c4872

File tree

4 files changed

+63
-15
lines changed

4 files changed

+63
-15
lines changed

elem.go

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,22 @@ var booleanAttrs = map[string]struct{}{
5353
attrs.Selected: {},
5454
}
5555

56+
type RenderOptions struct {
57+
// DisableHtmlPreamble disables the doctype preamble for the HTML tag if it exists in the rendering tree
58+
DisableHtmlPreamble bool
59+
}
60+
5661
type Node interface {
57-
RenderTo(builder *strings.Builder)
62+
RenderTo(builder *strings.Builder, opts RenderOptions)
5863
Render() string
64+
RenderWithOptions(opts RenderOptions) string
5965
}
6066

6167
// NoneNode represents a node that renders nothing.
6268
type NoneNode struct{}
6369

6470
// RenderTo for NoneNode does nothing.
65-
func (n NoneNode) RenderTo(builder *strings.Builder) {
71+
func (n NoneNode) RenderTo(builder *strings.Builder, opts RenderOptions) {
6672
// Intentionally left blank to render nothing
6773
}
6874

@@ -71,37 +77,54 @@ func (n NoneNode) Render() string {
7177
return ""
7278
}
7379

80+
// RenderWithOptions for NoneNode returns an empty string.
81+
func (n NoneNode) RenderWithOptions(opts RenderOptions) string {
82+
return ""
83+
}
84+
7485
type TextNode string
7586

76-
func (t TextNode) RenderTo(builder *strings.Builder) {
87+
func (t TextNode) RenderTo(builder *strings.Builder, opts RenderOptions) {
7788
builder.WriteString(string(t))
7889
}
7990

8091
func (t TextNode) Render() string {
8192
return string(t)
8293
}
8394

95+
func (t TextNode) RenderWithOptions(opts RenderOptions) string {
96+
return string(t)
97+
}
98+
8499
type RawNode string
85100

86-
func (r RawNode) RenderTo(builder *strings.Builder) {
101+
func (r RawNode) RenderTo(builder *strings.Builder, opts RenderOptions) {
87102
builder.WriteString(string(r))
88103
}
89104

90105
func (r RawNode) Render() string {
91106
return string(r)
92107
}
93108

109+
func (t RawNode) RenderWithOptions(opts RenderOptions) string {
110+
return string(t)
111+
}
112+
94113
type CommentNode string
95114

96-
func (c CommentNode) RenderTo(builder *strings.Builder) {
115+
func (c CommentNode) RenderTo(builder *strings.Builder, opts RenderOptions) {
97116
builder.WriteString("<!-- ")
98117
builder.WriteString(string(c))
99118
builder.WriteString(" -->")
100119
}
101120

102121
func (c CommentNode) Render() string {
122+
return c.RenderWithOptions(RenderOptions{})
123+
}
124+
125+
func (c CommentNode) RenderWithOptions(opts RenderOptions) string {
103126
var builder strings.Builder
104-
c.RenderTo(&builder)
127+
c.RenderTo(&builder, opts)
105128
return builder.String()
106129
}
107130

@@ -111,11 +134,11 @@ type Element struct {
111134
Children []Node
112135
}
113136

114-
func (e *Element) RenderTo(builder *strings.Builder) {
137+
func (e *Element) RenderTo(builder *strings.Builder, opts RenderOptions) {
115138
// The HTML tag needs a doctype preamble in order to ensure
116139
// browsers don't render in legacy/quirks mode
117140
// https://developer.mozilla.org/en-US/docs/Glossary/Doctype
118-
if e.Tag == "html" {
141+
if !opts.DisableHtmlPreamble && e.Tag == "html" {
119142
builder.WriteString("<!DOCTYPE html>")
120143
}
121144

@@ -146,7 +169,7 @@ func (e *Element) RenderTo(builder *strings.Builder) {
146169

147170
// Build the content
148171
for _, child := range e.Children {
149-
child.RenderTo(builder)
172+
child.RenderTo(builder, opts)
150173
}
151174

152175
// Append closing tag
@@ -174,8 +197,12 @@ func (e *Element) renderAttrTo(attrName string, builder *strings.Builder) {
174197
}
175198

176199
func (e *Element) Render() string {
200+
return e.RenderWithOptions(RenderOptions{})
201+
}
202+
203+
func (e *Element) RenderWithOptions(opts RenderOptions) string {
177204
var builder strings.Builder
178-
e.RenderTo(&builder)
205+
e.RenderTo(&builder, opts)
179206
return builder.String()
180207
}
181208

elements_test.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package elem
33
import (
44
"testing"
55

6-
"github.com/chasefleming/elem-go/styles"
7-
86
"github.com/chasefleming/elem-go/attrs"
97
"github.com/stretchr/testify/assert"
108
)
@@ -29,6 +27,18 @@ func TestHtml(t *testing.T) {
2927
assert.Equal(t, expected, el.Render())
3028
}
3129

30+
func TestHtmlWithOptions(t *testing.T) {
31+
expected := `<html lang="en"><head><meta charset="UTF-8"><title>Elem Page</title></head><body><p>Welcome to Elem!</p></body></html>`
32+
el := Html(attrs.Props{attrs.Lang: "en"},
33+
Head(nil,
34+
Meta(attrs.Props{attrs.Charset: "UTF-8"}),
35+
Title(nil, Text("Elem Page")),
36+
),
37+
Body(nil, P(nil, Text("Welcome to Elem!"))),
38+
)
39+
assert.Equal(t, expected, el.RenderWithOptions(RenderOptions{DisableHtmlPreamble: true}))
40+
}
41+
3242
// ========== Text Formatting and Structure ==========
3343

3444
func TestA(t *testing.T) {
@@ -269,7 +279,7 @@ func TestScript(t *testing.T) {
269279
func TestStyle(t *testing.T) {
270280
expected := `<style type="text/css">.test-class {color: #333;}</style>`
271281
cssContent := `.test-class {color: #333;}`
272-
el := Style(attrs.Props{attrs.Type: "text/css"}, styles.CSS(cssContent))
282+
el := Style(attrs.Props{attrs.Type: "text/css"}, TextNode(cssContent))
273283
assert.Equal(t, expected, el.Render())
274284
}
275285

styles/styles.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package styles
33
import (
44
"sort"
55
"strings"
6+
7+
"github.com/chasefleming/elem-go"
68
)
79

810
// Props is a map of CSS properties
@@ -38,7 +40,7 @@ func (p Props) ToInline() string {
3840
type CSSNode string
3941

4042
// RenderTo satisfies part of the Node interface by allowing CSSNode to be written to a strings.Builder
41-
func (cn CSSNode) RenderTo(builder *strings.Builder) {
43+
func (cn CSSNode) RenderTo(builder *strings.Builder, opts elem.RenderOptions) {
4244
builder.WriteString(string(cn))
4345
}
4446

styles/styles_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
package styles
22

33
import (
4-
"github.com/stretchr/testify/assert"
54
"testing"
5+
6+
"github.com/stretchr/testify/assert"
67
)
78

9+
func TestCSS(t *testing.T) {
10+
cssContent := `.test-class {color: #333;}`
11+
expected := `.test-class {color: #333;}`
12+
el := CSS(cssContent)
13+
assert.Equal(t, expected, el.Render())
14+
}
15+
816
func TestStyleToInline(t *testing.T) {
917
style := Props{
1018
BackgroundColor: "blue",
@@ -36,3 +44,4 @@ func TestStyleString_UnorderedKeys(t *testing.T) {
3644
}
3745
assert.Equal(t, "background-color: blue; color: white; font-size: 16px; outline-style: solid;", style.ToInline())
3846
}
47+

0 commit comments

Comments
 (0)