package html import "html" // --- 1. Content Safety and Interfaces --- // HTMLContent is the core interface for anything that can be rendered as part of the document. type HTMLContent interface { // Render returns the HTML string representation of the content. Render() string } // Text represents escaped text content. type Text struct { Value string } // Render automatically escapes the text content to prevent XSS. func (t Text) Render() string { return html.EscapeString(t.Value) } // T is a helper function that escapes text for safe rendering. func T(s string) Text { return Text{Value: s} } // Raw represents trusted HTML that should not be escaped. // Use this ONLY for known-safe content from trusted sources. type Raw string // Render returns the raw HTML without escaping. func (r Raw) Render() string { return string(r) } // --- 2. Element Structure and Generics --- // Attribute represents a single key/value HTML attribute for internal storage. type Attribute struct { Key string Value string } // basicElement is the concrete base struct used by all WebIDL-mapped elements. // The generic constraint C enforces the element's allowed content model. type basicElement[C HTMLContent] struct { tagName string attributes []Attribute content []C isVoid bool // True for self-closing tags like or
} // Render iterates over attributes and content to build the final HTML string. func (e *basicElement[C]) Render() string { var attrStr string // Concatenate attributes, escaping values. for _, attr := range e.attributes { attrStr += " " + attr.Key + "=\"" + html.EscapeString(attr.Value) + "\"" } if e.isVoid { // Void elements are self-closing return "<" + e.tagName + attrStr + " />" } var contentStr string // Recursively render content. for _, content := range e.content { contentStr += content.Render() } return "<" + e.tagName + attrStr + ">" + contentStr + "" }