Class: Tina4::HtmlElement

Inherits:
Object
  • Object
show all
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"))

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

Instance Method Summary collapse

Constructor Details

#initialize(tag, attrs = {}, children = []) ⇒ HtmlElement

Returns a new instance of HtmlElement.

Parameters:

  • tag (String)

    HTML tag name

  • attrs (Hash) (defaults to: {})

    attribute => value

  • children (Array) (defaults to: [])

    child elements (strings or HtmlElement instances)



54
55
56
57
58
# File 'lib/tina4/html_element.rb', line 54

def initialize(tag, attrs = {}, children = [])
  @tag = tag.to_s.downcase
  @attrs = attrs
  @children = children
end

Instance Attribute Details

#attrsObject (readonly)

Returns the value of attribute attrs.



49
50
51
# File 'lib/tina4/html_element.rb', line 49

def attrs
  @attrs
end

#childrenObject (readonly)

Returns the value of attribute children.



49
50
51
# File 'lib/tina4/html_element.rb', line 49

def children
  @children
end

#tagObject (readonly)

Returns the value of attribute tag.



49
50
51
# File 'lib/tina4/html_element.rb', line 49

def tag
  @tag
end

Instance Method Details

#call(*args) ⇒ HtmlElement

Builder pattern — appends children and/or merges attributes.

Parameters:

  • args (Array)

    Strings, HtmlElements, Hashes (treated as attrs), or Arrays

Returns:

  • (HtmlElement)

    a new HtmlElement with the appended children



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/tina4/html_element.rb', line 64

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_sObject

Render to HTML string.



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/tina4/html_element.rb', line 83

def to_s
  html = "<#{@tag}"

  @attrs.each do |key, value|
    case value
    when true
      html << " #{key}"
    when false, nil
      next
    else
      escaped = value.to_s
        .gsub("&", "&amp;")
        .gsub('"', "&quot;")
        .gsub("<", "&lt;")
        .gsub(">", "&gt;")
      html << " #{key}=\"#{escaped}\""
    end
  end

  if VOID_TAGS.include?(@tag)
    html << ">"
    return html
  end

  html << ">"

  @children.each do |child|
    html << child.to_s
  end

  html << "</#{@tag}>"
  html
end