module Hpricot::Container::Trav

def classes

Returns a list of CSS classes to which this element belongs.
def classes
  get_attribute('class').to_s.strip.split(/\s+/)
end

def containers

aren't text, comment, doctype or processing instruction nodes.
nodes. This is a good way to get all HTML elements which
Return all children of this node which can contain other
def containers
  children.grep(Container::Trav)
end

def each_child(&block) # :yields: child_node

:yields: child_node
+each_child+ iterates over each child.
def each_child(&block) # :yields: child_node
  children.each(&block)
  nil
end

def each_child_with_index(&block) # :yields: child_node, index

:yields: child_node, index
+each_child_with_index+ iterates over each child.
def each_child_with_index(&block) # :yields: child_node, index
  children.each_with_index(&block)
  nil
end

def each_hyperlink # :yields: text

:yields: text
Note that +each_hyperlink+ yields HTML href attribute of BASE element.

It yields Hpricot::Text.

of A element.
+each_hyperlink+ traverses hyperlinks such as HTML href attribute
def each_hyperlink # :yields: text
  links = []
  each_hyperlink_attribute {|elem, attr, hyperlink|
    yield hyperlink
  }
end

def each_hyperlink_attribute

def each_hyperlink_attribute
  traverse_element(
      '{http://www.w3.org/1999/xhtml}a',
      '{http://www.w3.org/1999/xhtml}area',
      '{http://www.w3.org/1999/xhtml}link',
      '{http://www.w3.org/1999/xhtml}img',
      '{http://www.w3.org/1999/xhtml}object',
      '{http://www.w3.org/1999/xhtml}q',
      '{http://www.w3.org/1999/xhtml}blockquote',
      '{http://www.w3.org/1999/xhtml}ins',
      '{http://www.w3.org/1999/xhtml}del',
      '{http://www.w3.org/1999/xhtml}form',
      '{http://www.w3.org/1999/xhtml}input',
      '{http://www.w3.org/1999/xhtml}head',
      '{http://www.w3.org/1999/xhtml}base',
      '{http://www.w3.org/1999/xhtml}script') {|elem|
    case elem.name
    when %r{\{http://www.w3.org/1999/xhtml\}(?:base|a|area|link)\z}i
      attrs = ['href']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:img)\z}i
      attrs = ['src', 'longdesc', 'usemap']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:object)\z}i
      attrs = ['classid', 'codebase', 'data', 'usemap']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:q|blockquote|ins|del)\z}i
      attrs = ['cite']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:form)\z}i
      attrs = ['action']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:input)\z}i
      attrs = ['src', 'usemap']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:head)\z}i
      attrs = ['profile']
    when %r{\{http://www.w3.org/1999/xhtml\}(?:script)\z}i
      attrs = ['src', 'for']
    end
    attrs.each {|attr|
      if hyperlink = elem.get_attribute(attr)
        yield elem, attr, hyperlink
      end
    }
  }
end

def each_hyperlink_uri(base_uri=nil) # :yields: hyperlink, uri

:yields: hyperlink, uri
+each_hyperlink_uri+ doesn't yields href of the BASE element.
HTML BASE element or the argument ((|base_uri|)).
The URI objects are created with a base URI which is given by

It yields Hpricot::Text and URI for each hyperlink.

of A element.
+each_hyperlink_uri+ traverses hyperlinks such as HTML href attribute
def each_hyperlink_uri(base_uri=nil) # :yields: hyperlink, uri
  base_uri = URI.parse(base_uri) if String === base_uri
  links = []
  each_hyperlink_attribute {|elem, attr, hyperlink|
    if %r{\{http://www.w3.org/1999/xhtml\}(?:base)\z}i =~ elem.name
      base_uri = URI.parse(hyperlink.to_s)
    else
      links << hyperlink
    end
  }
  if base_uri
    links.each {|hyperlink| yield hyperlink, base_uri + hyperlink.to_s }
  else
    links.each {|hyperlink| yield hyperlink, URI.parse(hyperlink.to_s) }
  end
end

def each_uri(base_uri=nil) # :yields: URI

:yields: URI
HTML BASE element or the argument ((|base_uri|)).
The URI objects are created with a base URI which is given by

It yields URI for each hyperlink.

of A element.
+each_uri+ traverses hyperlinks such as HTML href attribute
def each_uri(base_uri=nil) # :yields: URI
  each_hyperlink_uri(base_uri) {|hyperlink, uri| yield uri }
end

def filter(&block)


It doesn't return location object even if self is location object.
+filter+ returns an node.

inner nodes are examined.
If given block returns true, corresponding node is retained and
If given block returns false, corresponding node is dropped.
+filter+ yields each node except top node.

loc.filter {|descendant_loc| predicate } -> node
node.filter {|descendant_node| predicate } -> node

+filter+ rebuilds the tree without some components.
def filter(&block)
  subst = {}
  each_child_with_index {|descendant, i|
    if yield descendant
      if descendant.elem?
        subst[i] = descendant.filter(&block)
      else
        subst[i] = descendant
      end
    else
      subst[i] = nil
    end
  }
  to_node.subst_subnode(subst)
end

def find_element(*names)

It returns nil if not found.
the arguments.
+find_element+ searches an element which universal name is specified by
def find_element(*names)
  traverse_element(*names) {|e| return e }
  nil
end

def following_siblings()

out text and comment nodes.
Find sibling elements which follow the current one. Like the other "sibling" methods, this weeds
def following_siblings() 
  sibs = parent.containers 
  si = sibs.index(self) + 1 
  return Elements[*sibs[si...sibs.length]] 
end 

def get_element_by_id(id)

def get_element_by_id(id)
  traverse_all_element do |ele|
      if ele.elem? and eid = ele.get_attribute('id')
          return ele if eid.to_s == id
      end
  end
  nil
end

def get_elements_by_tag_name(*a)

def get_elements_by_tag_name(*a)
  list = Elements[]
  a.delete("*")
  traverse_element(*a.map { |tag| [tag, "{http://www.w3.org/1999/xhtml}#{tag}"] }.flatten) do |e|
    list << e if e.elem?
  end
  list
end

def insert_after(nodes, ele)

after the node +ele+, a child of the current node.
Insert +nodes+, an array of HTML elements or a single element,
def insert_after(nodes, ele)
  case nodes
  when Array
    nodes.reverse_each { |n| insert_after(n, ele) }
  else
    reparent nodes
    idx = children.index(ele)
    children[idx ? idx + 1 : children.length, 0] = nodes
  end
end

def insert_before(nodes, ele)

before the node +ele+, a child of the current node.
Insert +nodes+, an array of HTML elements or a single element,
def insert_before(nodes, ele)
  case nodes
  when Array
    nodes.each { |n| insert_before(n, ele) }
  else
    reparent nodes
    children[children.index(ele) || 0, 0] = nodes
  end
end

def next_sibling

See Hpricot::Traverse#next_node if you need to hunt out all kinds of nodes.
By "container" node, I mean: this method does not find text nodes or comments or cdata or any of that.
Returns the container node neighboring this node to the south: just below it.
def next_sibling
  sib = parent.containers
  sib[sib.index(self) + 1] if parent
end

def preceding_siblings()

out text and comment nodes.
Find all preceding sibling elements. Like the other "sibling" methods, this weeds
def preceding_siblings() 
  sibs = parent.containers 
  si = sibs.index(self) 
  return Elements[*sibs[0...si]] 
end 

def previous_sibling

See Hpricot::Traverse#previous_node if you need to hunt out all kinds of nodes.
By "container" node, I mean: this method does not find text nodes or comments or cdata or any of that.
Returns the container node neighboring this node to the north: just above it.
def previous_sibling
  sib = parent.containers
  x = sib.index(self) - 1
  sib[x] if sib and x >= 0
end

def replace_child(old, new)

Replace +old+, a child of the current node, with +new+ node.
def replace_child(old, new)
  reparent new
  children[children.index(old), 1] = [*new]
end

def siblings_at(*pos)

Use nodes_at to include those nodes.
Like the other "sibling" methods, this doesn't find text and comment nodes.

ele.siblings_at(0, 5..6) # the current element and two others
ele.siblings_at(1, 5, 7) # gets three elements at offsets below the current element
ele.siblings_at(-3..-1, 1..3) # gets three elements before and three after

This method accepts ranges and sets of numbers.

to this element.
Puts together an array of neighboring sibling elements based on their proximity
def siblings_at(*pos)
  sib = parent.containers
  i, si = 0, sib.index(self)
  Elements[*
    sib.select do |x|
      sel = case i - si when *pos
              true
            end
      i += 1
      sel
    end
  ]
end

def traverse_text_internal(&block)

def traverse_text_internal(&block)
  each_child {|c| c.traverse_text_internal(&block) }
end