/
builder_methods.rb
83 lines (65 loc) · 2.2 KB
/
builder_methods.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
module Arbre
class Element
module BuilderMethods
def self.included(klass)
klass.extend ClassMethods
end
module ClassMethods
def builder_method(method_name)
BuilderMethods.class_eval <<-EOF, __FILE__, __LINE__
def #{method_name}(*args, &block)
insert_tag ::#{self.name}, *args, &block
end
EOF
end
end
def build_tag(klass, *args, &block)
tag = klass.new(arbre_context)
tag.parent = current_arbre_element
with_current_arbre_element tag do
if block_given? && block.arity > 0
tag.build(*args, &block)
else
tag.build(*args)
append_return_block(yield) if block_given?
end
end
tag
end
def insert_tag(klass, *args, &block)
tag = build_tag(klass, *args, &block)
current_arbre_element.add_child(tag)
tag
end
def current_arbre_element
arbre_context.current_arbre_element
end
def with_current_arbre_element(tag, &block)
arbre_context.with_current_arbre_element(tag, &block)
end
alias_method :within, :with_current_arbre_element
private
# Appends the value to the current DOM element if there are no
# existing DOM Children and it responds to #to_s
def append_return_block(tag)
return nil if current_arbre_element.children?
if appendable_tag?(tag)
current_arbre_element << Arbre::HTML::TextNode.from_string(tag.to_s)
end
end
# Returns true if the object should be converted into a text node
# and appended into the DOM.
def appendable_tag?(tag)
is_appendable = !tag.is_a?(Arbre::Element) && tag.respond_to?(:to_s)
# In ruby 1.9, Arraay.new.to_s prints out an empty array ("[]"). In
# Arbre, we append the return value of blocks to the output, which
# can cause empty arrays to show up within the output. To get
# around this, we check if the object responds to #empty?
if tag.respond_to?(:empty?) && tag.empty?
is_appendable = false
end
is_appendable
end
end
end
end