Class: Hpricot::Elements

Inherits:
Array
  • Object
show all
Defined in:
lib/hpricot/inspect.rb,
lib/hpricot/elements.rb

Overview

and Hpricot::Container::Trav.

Constant Summary collapse

ATTR_RE =
%r!\[ *(?:(@)([\w\(\)-]+)|([\w\(\)-]+\(\))) *([~\!\|\*$\^=]*) *'?"?([^'"]*)'?"? *\]!i
BRACK_RE =
%r!(\[) *([^\]]*) *\]!i
FUNC_RE =
%r!(:)?([a-zA-Z0-9\*_-]*)\( *[\"']?([^ \)]*?)['\"]? *\)!
CATCH_RE =
%r!([:\.#]*)([a-zA-Z0-9\*_-]+)!

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.filter(nodes, expr, truth = true) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/hpricot/elements.rb', line 201

def self.filter(nodes, expr, truth = true)
    until expr.empty?
        _, *m = *expr.match(/^(?:#{ATTR_RE}|#{BRACK_RE}|#{FUNC_RE}|#{CATCH_RE})/)
        break unless _

        expr = $'
        m.compact!
        if m[0] == '@'
            m[0] = "@#{m.slice!(2,1)}"
        end

        if m[0] == '[' && m[1] =~ /^\d+$/
            m = [":", "nth", m[1].to_i-1]
        end

        if m[0] == ":" && m[1] == "not"
            nodes, = Elements.filter(nodes, m[2], false)
        else
            meth = "filter[#{m[0]}#{m[1]}]"
            if Traverse.method_defined? meth
                args = m[2..-1]
            else
                meth = "filter[#{m[0]}]"
                if Traverse.method_defined? meth
                    args = m[1..-1]
                end
            end
            i = -1
            nodes = Elements[*nodes.find_all do |x| 
                                  i += 1
                                  x.send(meth, *([*args] + [i])) ? truth : !truth
                              end]
        end
    end
    [nodes, expr]
end

Instance Method Details

#after(str) ⇒ Object

Just after each element in this list, add some HTML. Pass in an HTML str, which is turned into Hpricot elements.



149
150
151
# File 'lib/hpricot/elements.rb', line 149

def after(str)
  each { |x| x.parent.insert_after Hpricot.make(str), x }
end

#append(str) ⇒ Object

Add to the end of the contents inside each element in this list. Pass in an HTML str, which is turned into Hpricot elements.



131
132
133
# File 'lib/hpricot/elements.rb', line 131

def append(str)
  each { |x| x.inner_html += str }
end

#at(expr, &blk) ⇒ Object Also known as: %

Searches this list for the first element (or child of these elements) matching the CSS or XPath expression expr. Root is assumed to be the element scanned.

See Hpricot::Container::Trav.at for more.



66
67
68
# File 'lib/hpricot/elements.rb', line 66

def at(expr, &blk)
  search(expr, &blk).first
end

#before(str) ⇒ Object

Add some HTML just previous to each element in this list. Pass in an HTML str, which is turned into Hpricot elements.



143
144
145
# File 'lib/hpricot/elements.rb', line 143

def before(str)
  each { |x| x.parent.insert_before Hpricot.make(str), x }
end

#emptyObject

Empty the elements in this list, by removing their insides.

doc = Hpricot("<p> We have <i>so much</i> to say.</p>")
doc.search("i").empty
doc.to_html
  => "<p> We have <i></i> to say.</p>"


125
126
127
# File 'lib/hpricot/elements.rb', line 125

def empty
  each { |x| x.inner_html = nil }
end

#filter(expr) ⇒ Object



238
239
240
241
# File 'lib/hpricot/elements.rb', line 238

def filter(expr)
    nodes, = Elements.filter(self, expr)
    nodes
end

#inner_html(*string) ⇒ Object Also known as: html, innerHTML

Returns an HTML fragment built of the contents of each element in this list.

If a HTML string is supplied, this method acts like inner_html=.



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

def inner_html(*string)
  if string.empty?
    map { |x| x.inner_html }.join
  else
    x = self.inner_html = string.pop || x
  end
end

#inner_html=(string) ⇒ Object Also known as: html=, innerHTML=

Replaces the contents of each element in this list. Supply an HTML string, which is loaded into Hpricot objects and inserted into every element in this list.



94
95
96
# File 'lib/hpricot/elements.rb', line 94

def inner_html=(string)
  each { |x| x.inner_html = string }
end

#inner_textObject Also known as: text

Returns an string containing the text contents of each element in this list. All HTML tags are removed.



102
103
104
# File 'lib/hpricot/elements.rb', line 102

def inner_text
  map { |x| x.inner_text }.join
end

#not(expr) ⇒ Object



243
244
245
246
247
248
249
250
# File 'lib/hpricot/elements.rb', line 243

def not(expr)
    if expr.is_a? Traverse
        nodes = self - [expr]
    else
        nodes, = Elements.filter(self, expr, false)
    end
    nodes
end

#prepend(str) ⇒ Object

Add to the start of the contents inside each element in this list. Pass in an HTML str, which is turned into Hpricot elements.



137
138
139
# File 'lib/hpricot/elements.rb', line 137

def prepend(str)
  each { |x| x.inner_html = str + x.inner_html }
end

#pretty_print(q) ⇒ Object



6
7
8
# File 'lib/hpricot/inspect.rb', line 6

def pretty_print(q)
  q.object_group(self) { super }
end

#removeObject

Remove all elements in this list from the document which contains them.

doc = Hpricot("<html>Remove this: <b>here</b></html>")
doc.search("b").remove
doc.to_html
  => "<html>Remove this: </html>"


114
115
116
# File 'lib/hpricot/elements.rb', line 114

def remove
  each { |x| x.parent.children.delete(x) }
end

#search(*expr, &blk) ⇒ Object Also known as: /

Searches this list for any elements (or children of these elements) matching the CSS or XPath expression expr. Root is assumed to be the element scanned.

See Hpricot::Container::Trav.search for more.



57
58
59
# File 'lib/hpricot/elements.rb', line 57

def search(*expr,&blk)
  Elements[*map { |x| x.search(*expr,&blk) }.flatten.uniq]
end

#set(k, v = nil) ⇒ Object

Sets an attribute for all elements in this list. You may use a simple pair (attribute name, attribute value):

doc.search('p').set(:class, 'outline')

Or, use a hash of pairs:

doc.search('div#sidebar').set(:class => 'outline', :id => 'topbar')


183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/hpricot/elements.rb', line 183

def set(k, v = nil)
  case k
  when Hash
    each do |node|
      k.each { |a,b| node.set_attribute(a, b) }
    end
  else
    each do |node|
      node.set_attribute(k, v)
    end
  end
end

#to_htmlObject Also known as: to_s

Convert this group of elements into a complete HTML fragment, returned as a string.



73
74
75
# File 'lib/hpricot/elements.rb', line 73

def to_html
  map { |x| x.output("") }.join
end

#wrap(str) ⇒ Object

Wraps each element in the list inside the element created by HTML str. If more than one element is found in the string, Hpricot locates the deepest spot inside the first element.

doc.search("a[@href]").
    wrap(%{<div class="link"><div class="link_inner"></div></div>})

This code wraps every link on the page inside a div.link and a div.link_inner nest.



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/hpricot/elements.rb', line 161

def wrap(str)
  each do |x|
    wrap = Hpricot.make(str)
    nest = wrap.detect { |w| w.respond_to? :children }
    unless nest
      raise Exception, "No wrapping element found."
    end
    x.parent.replace_child(x, wrap)
    nest = nest.children.first until nest.empty?
    nest.children << x
  end
end