Class: Undies::Element

Inherits:
Node
  • Object
show all
Defined in:
lib/undies/element.rb

Constant Summary collapse

ID_METH_REGEX =

CSS proxy methods ============================================

/^([^_].+)!$/
CLASS_METH_REGEX =
/^([^_].+)$/

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

#force_pp?

Constructor Details

#initialize(name, attrs = {}, &block) ⇒ Element

Returns a new instance of Element.



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/undies/element.rb', line 50

def initialize(name, attrs={}, &block)
  if !attrs.kind_of?(::Hash)
    raise ArgumentError, "#{name.inspect} attrs must be provided as a Hash."
  end

  @name  = name.to_s
  @attrs = attrs
  @content_blocks = []
  @content_blocks << block if block
  @start_tag = start_tag
  @end_tag = end_tag
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/undies/element.rb', line 67

def method_missing(meth, *args, &block)
  if meth.to_s =~ ID_METH_REGEX
    proxy($1, args.first || {}, block) do |value|
      @attrs.merge!(:id => value)
    end
  elsif meth.to_s =~ CLASS_METH_REGEX
    proxy($1, args.first || {}, block) do |value|
      @attrs[:class] = [@attrs[:class], value].compact.join(' ')
    end
  else
    super
  end
end

Class Method Details

.content(element) ⇒ Object



32
33
34
# File 'lib/undies/element.rb', line 32

def self.content(element)
  nil
end

.escape_attr_value(value) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/undies/element.rb', line 24

def self.escape_attr_value(value)
  value.
    to_s.
    gsub('&', '&amp;').
    gsub('<', '&lt;').
    gsub('"', '&quot;')
end

.flush(output, element) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/undies/element.rb', line 36

def self.flush(output, element)
  output.pp_use_indent = true
  output << element.instance_variable_get("@start_tag")
  if (cbs = element.instance_variable_get("@content_blocks")).size > 0
    output.pp_level += 1
    output.pp_use_indent = false
    cbs.each{ |content| content.call }
    output.flush
    output.pp_level -= 1
  end
  output << element.instance_variable_get("@end_tag") if element.instance_variable_get("@end_tag")
  output.pp_use_indent = true
end

.hash_attrs(attrs = "", ns = nil) ⇒ Object

have as many methods to the class level as possilbe to keep from polluting the public instance methods and to maximize the effectiveness of the Element#method_missing logic



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/undies/element.rb', line 10

def self.hash_attrs(attrs="", ns=nil)
  return attrs.to_s if !attrs.kind_of?(::Hash)

  {}.tap do |a|
    attrs.each { |k, v| a[ns ? "#{ns}_#{k}" : k.to_s] = v }
  end.sort.inject('') do |html, k_v|
    html + if k_v.last.kind_of?(::Hash)
      hash_attrs(k_v.last, k_v.first)
    else
      " #{k_v.first}=\"#{escape_attr_value(k_v.last)}\""
    end
  end
end

Instance Method Details

#==(other) ⇒ Object



90
91
92
93
94
# File 'lib/undies/element.rb', line 90

def ==(other)
  other.instance_variable_get("@name")  == @name  &&
  other.instance_variable_get("@attrs") == @attrs &&
  other.instance_variable_get("@nodes") == @nodes
end

#respond_to?(*args) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
87
# File 'lib/undies/element.rb', line 81

def respond_to?(*args)
  if args.first.to_s =~ ID_METH_REGEX || args.first.to_s =~ CLASS_METH_REGEX
    true
  else
    super
  end
end

#to_str(*args) ⇒ Object Also known as: inspect

overriding this because the base Node class defines a ‘to_s’ method that needs to be honored



98
99
100
101
# File 'lib/undies/element.rb', line 98

def to_str(*args)
  "Undies::Element:#{self.object_id} " +
  "@name=#{@name.inspect}, @attrs=#{@attrs.inspect}, @nodes=#{@nodes.inspect}"
end