Class: Tina4::HtmlElement
- Inherits:
-
Object
- Object
- Tina4::HtmlElement
- Defined in:
- lib/tina4/html_element.rb
Overview
Programmatic HTML builder — avoids string concatenation.
Usage:
el = Tina4::HtmlElement.new("div", { class: "card" }, ["Hello"])
el.to_s # => '<div class="card">Hello</div>'
# Builder pattern (via call)
el = Tina4::HtmlElement.new("div").call(Tina4::HtmlElement.new("p").call("Text"))
# Helper functions
include Tina4::HtmlHelpers
html = _div({ class: "card" }, _p("Hello"))
String/scalar children are HTML-escaped by default to defeat XSS; nested HtmlElement children render themselves (already escaped, no double-escape); a Raw / SafeString child renders verbatim (explicit opt-in for trusted markup).
Constant Summary collapse
- VOID_TAGS =
%w[ area base br col embed hr img input link meta param source track wbr ].freeze
- HTML_TAGS =
%w[ a abbr address area article aside audio b base bdi bdo blockquote body br button canvas caption cite code col colgroup data datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd label legend li link main map mark menu meta meter nav noscript object ol optgroup option output p param picture pre progress q rp rt ruby s samp script section select slot small source span strong style sub summary sup table tbody td template textarea tfoot th thead time title tr track u ul var video wbr ].freeze
Instance Attribute Summary collapse
-
#attrs ⇒ Object
readonly
Returns the value of attribute attrs.
-
#children ⇒ Object
readonly
Returns the value of attribute children.
-
#tag ⇒ Object
readonly
Returns the value of attribute tag.
Instance Method Summary collapse
-
#call(*args) ⇒ HtmlElement
Builder pattern — appends children and/or merges attributes.
-
#initialize(tag, attrs = {}, children = []) ⇒ HtmlElement
constructor
A new instance of HtmlElement.
-
#to_s ⇒ Object
Render to HTML string.
Constructor Details
#initialize(tag, attrs = {}, children = []) ⇒ HtmlElement
Returns a new instance of HtmlElement.
81 82 83 84 85 |
# File 'lib/tina4/html_element.rb', line 81 def initialize(tag, attrs = {}, children = []) @tag = tag.to_s.downcase @attrs = attrs @children = children end |
Instance Attribute Details
#attrs ⇒ Object (readonly)
Returns the value of attribute attrs.
76 77 78 |
# File 'lib/tina4/html_element.rb', line 76 def attrs @attrs end |
#children ⇒ Object (readonly)
Returns the value of attribute children.
76 77 78 |
# File 'lib/tina4/html_element.rb', line 76 def children @children end |
#tag ⇒ Object (readonly)
Returns the value of attribute tag.
76 77 78 |
# File 'lib/tina4/html_element.rb', line 76 def tag @tag end |
Instance Method Details
#call(*args) ⇒ HtmlElement
Builder pattern — appends children and/or merges attributes.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/tina4/html_element.rb', line 91 def call(*args) new_attrs = @attrs.dup new_children = @children.dup args.each do |arg| case arg when Hash new_attrs = new_attrs.merge(arg) when Array new_children.concat(arg) else new_children << arg end end self.class.new(@tag, new_attrs, new_children) end |
#to_s ⇒ Object
Render to HTML string.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/tina4/html_element.rb', line 110 def to_s html = "<#{@tag}" @attrs.each do |key, value| case value when true html << " #{key}" when false, nil next else html << " #{key}=\"#{escape_text(value.to_s)}\"" end end if VOID_TAGS.include?(@tag) html << ">" return html end html << ">" @children.each do |child| case child when HtmlElement # Nested elements render themselves (they already escape their own # children) — emit as-is to avoid double-escaping. html << child.to_s when Raw # Explicitly trusted markup — emit unescaped. Raw subclasses String, # so this branch MUST come before the generic scalar escape below. html << child.to_s else # Plain string/scalar child — escape to defeat stored/reflected XSS. html << escape_text(child.to_s) end end html << "</#{@tag}>" html end |