Class: Former::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/former/builder.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(html) ⇒ Builder

Returns a new instance of Builder.



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
# File 'lib/former/builder.rb', line 8

def initialize(html)
  @html = Nokogiri::HTML.parse(html)

  matches = {}
  self.class.queries.each do |path, qs|
    @html.search(path).each do |node| 
      # if all we need is the text, only include text kids
      if qs.length == 1 and qs.first[:query] == :text
        node.traverse { |e| matches[e] = qs if e.text? and not matches.keys.include? e }
      else
        # otherwise, ignore just text requests
        matches[node] = qs.select { |q| q[:query] != :text }
      end
    end
  end

  @editable = []
  @html.traverse_prefix do |e|
    (matches[e] || []).each do |query|
      if query[:block].nil? or query[:block].call(e)
        @editable << Element.new(e, query[:query], @editable.length, query[:args])
      end
    end
  end
  
  # if we were given text only (no html), nokogiri will helpfully
  # wrap it in a <p> - but our output should just be text.  So remember.
  @nothtml = (@editable.length == 1 and @html.text == html)
end

Class Attribute Details

.queriesObject

Returns the value of attribute queries.



5
6
7
# File 'lib/former/builder.rb', line 5

def queries
  @queries
end

Instance Attribute Details

#editableObject (readonly)

Returns the value of attribute editable.



6
7
8
# File 'lib/former/builder.rb', line 6

def editable
  @editable
end

Class Method Details

.attr(elem, attr, args = nil, &block) ⇒ Object



69
70
71
72
73
# File 'lib/former/builder.rb', line 69

def self.attr(elem, attr, args=nil, &block)
  @queries ||= {}
  @queries[elem] ||= []
  @queries[elem] << { :query => attr, :block => block, :args => args }
end

.style_url(property, &block) ⇒ Object



80
81
82
83
84
# File 'lib/former/builder.rb', line 80

def self.style_url(property, &block)
  attr("[@style]", :style_url, { :property => property }) { |elem|
    elem['style'].include? property and (block_given? ? block.call(elem) : true)
  }
end

.text(*elems, &block) ⇒ Object



75
76
77
78
# File 'lib/former/builder.rb', line 75

def self.text(*elems, &block)
  attr("text()", :text, &block) if elems.length == 0
  elems.each { |elem| attr(elem, :text, &block) }
end

Instance Method Details

#[]=(index, value) ⇒ Object



58
59
60
# File 'lib/former/builder.rb', line 58

def []=(index, value)
  @editable[index].value = value
end

#each(&block) ⇒ Object



42
43
44
# File 'lib/former/builder.rb', line 42

def each(&block)
  @editable.each { |e| block.call(e) }
end

#lengthObject



38
39
40
# File 'lib/former/builder.rb', line 38

def length
  @editable.length
end

#set_values(vals) ⇒ Object

vals should be { :former_0 => ‘value’, :former_1 => ‘value two’, … }



63
64
65
66
67
# File 'lib/former/builder.rb', line 63

def set_values(vals)
  vals.each { |key, value|
    self[key.to_s.split('_').last.to_i] = value
  }
end

#to_htmlObject



50
51
52
53
54
55
56
# File 'lib/former/builder.rb', line 50

def to_html
  return @html.text if @nothtml
  # nokogiri pads w/ html/body elements
  @html.xpath("/html/body").children.map { |c|
    c.serialize(:save_with => Nokogiri::XML::Node::SaveOptions::AS_HTML).strip
  }.join
end

#to_jsonObject



46
47
48
# File 'lib/former/builder.rb', line 46

def to_json
  "[" + @editable.map(&:to_json).join(",") + "]"
end