diff --git a/elem.go b/elem.go index 56be5ff..a393439 100644 --- a/elem.go +++ b/elem.go @@ -92,15 +92,15 @@ func (n NoneNode) RenderWithOptions(opts RenderOptions) string { type TextNode string func (t TextNode) RenderTo(builder *strings.Builder, opts RenderOptions) { - builder.WriteString(string(t)) + builder.WriteString(EscapeNodeContents(string(t))) } func (t TextNode) Render() string { - return string(t) + return EscapeNodeContents(string(t)) } func (t TextNode) RenderWithOptions(opts RenderOptions) string { - return string(t) + return EscapeNodeContents(string(t)) } type RawNode string diff --git a/elements.go b/elements.go index 6b57945..066215d 100644 --- a/elements.go +++ b/elements.go @@ -143,7 +143,8 @@ func U(attrs attrs.Props, children ...Node) *Element { return newElement("u", attrs, children...) } -// Text creates a TextNode. +// Text creates a TextNode, content is automatically escaped to ensure safe rendering. +// For unescaped HTML, use Raw function instead. func Text(content string) TextNode { return TextNode(content) } diff --git a/elements_test.go b/elements_test.go index 223163c..369103c 100644 --- a/elements_test.go +++ b/elements_test.go @@ -673,6 +673,24 @@ func TestNoneInDiv(t *testing.T) { assert.Equal(t, expected, actual) } +func TestText(t *testing.T) { + expected := `
Hello, World!
` + el := P(nil, Text("Hello, World!")) + assert.Equal(t, expected, el.Render()) +} + +func TestTextWithEscaping(t *testing.T) { + expected := `Hello, <em>World!</em>
` + el := P(nil, Text("Hello, World!")) + assert.Equal(t, expected, el.Render()) +} + +func TestTextWithNoQuotesEscaping(t *testing.T) { + expected := `'Hello,' "World!"
` + el := P(nil, Text(`'Hello,' "World!"`)) + assert.Equal(t, expected, el.Render()) +} + func TestRaw(t *testing.T) { rawHTML := `Test paragraph