Module: Hpricot::Container::Trav

Includes:
Traverse
Included in:
Doc::Trav, Elem::Trav
Defined in:
lib/ext/hpricot/traverse.rb,
lib/ext/hpricot/modules.rb,
lib/ext/hpricot/traverse.rb,
lib/ext/hpricot/traverse.rb

Overview

:startdoc:

Instance Method Summary collapse

Methods included from Traverse

#after, #at, #before, #bogusetag?, #children_of_type, #clean_path, #comment?, #css_path, #doc?, #doctype?, #elem?, filter, #following, #get_subnode, #html, #index, #inner_html=, #inner_text, #make, #next, #node_position, #nodes_at, #position, #preceding, #previous, #procins?, #search, #swap, #text?, #to_html, #to_original_html, #to_plain_text, #traverse_element, #traverse_text, #xmldecl?, #xpath

Instance Method Details

#classesObject

Returns a list of CSS classes to which this element belongs.



517
518
519
# File 'lib/ext/hpricot/traverse.rb', line 517

def classes
  get_attribute('class').to_s.strip.split(/\s+/)
end

#containersObject

Return all children of this node which can contain other nodes. This is a good way to get all HTML elements which aren’t text, comment, doctype or processing instruction nodes.



403
404
405
# File 'lib/ext/hpricot/traverse.rb', line 403

def containers
  children.grep(Container::Trav)
end

#each_child(&block) ⇒ Object

each_child iterates over each child.



497
498
499
500
# File 'lib/ext/hpricot/traverse.rb', line 497

def each_child(&block) # :yields: child_node
  children.each(&block) if children
  nil
end

#each_child_with_index(&block) ⇒ Object

each_child_with_index iterates over each child.



503
504
505
506
# File 'lib/ext/hpricot/traverse.rb', line 503

def each_child_with_index(&block) # :yields: child_node, index
  children.each_with_index(&block) if children
  nil
end

each_hyperlink traverses hyperlinks such as HTML href attribute of A element.

It yields Hpricot::Text.

Note that each_hyperlink yields HTML href attribute of BASE element.



613
614
615
616
617
618
# File 'lib/ext/hpricot/traverse.rb', line 613

def each_hyperlink # :yields: text
  links = []
  each_hyperlink_attribute {|elem, attr, hyperlink|
    yield hyperlink
  }
end

each_hyperlink_uri traverses hyperlinks such as HTML href attribute of A element.

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

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



590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
# File 'lib/ext/hpricot/traverse.rb', line 590

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

#each_uri(base_uri = nil) ⇒ Object

each_uri traverses hyperlinks such as HTML href attribute of A element.

It yields URI for each hyperlink.

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



627
628
629
# File 'lib/ext/hpricot/traverse.rb', line 627

def each_uri(base_uri=nil) # :yields: URI
  each_hyperlink_uri(base_uri) {|hyperlink, uri| yield uri }
end

#filter(&block) ⇒ Object

filter rebuilds the tree without some components.

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

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

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



718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
# File 'lib/ext/hpricot/traverse.rb', line 718

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

#find_element(*names) ⇒ Object

find_element searches an element which universal name is specified by the arguments. It returns nil if not found.



511
512
513
514
# File 'lib/ext/hpricot/traverse.rb', line 511

def find_element(*names)
  traverse_element(*names) {|e| return e }
  nil
end

#following_siblingsObject

Find sibling elements which follow the current one. Like the other “sibling” methods, this weeds out text and comment nodes.



434
435
436
437
438
# File 'lib/ext/hpricot/traverse.rb', line 434

def following_siblings() 
  sibs = parent.containers 
  si = sibs.index(self) + 1 
  return Elements[*sibs[si...sibs.length]] 
end

#get_element_by_id(id) ⇒ Object



521
522
523
524
525
526
527
528
# File 'lib/ext/hpricot/traverse.rb', line 521

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

#get_elements_by_tag_name(*a) ⇒ Object



530
531
532
533
534
535
536
537
# File 'lib/ext/hpricot/traverse.rb', line 530

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

#insert_after(nodes, ele) ⇒ Object

Insert nodes, an array of HTML elements or a single element, after the node ele, a child of the current node.



485
486
487
488
489
490
491
492
493
494
# File 'lib/ext/hpricot/traverse.rb', line 485

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

#insert_before(nodes, ele) ⇒ Object

Insert nodes, an array of HTML elements or a single element, before the node ele, a child of the current node.



473
474
475
476
477
478
479
480
481
# File 'lib/ext/hpricot/traverse.rb', line 473

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

#next_siblingObject

Returns the container node neighboring this node to the south: just below it. By “container” node, I mean: this method does not find text nodes or comments or cdata or any of that. See Hpricot::Traverse#next_node if you need to hunt out all kinds of nodes.



410
411
412
413
# File 'lib/ext/hpricot/traverse.rb', line 410

def next_sibling
  sib = parent.containers
  sib[sib.index(self) + 1] if parent
end

#preceding_siblingsObject

Find all preceding sibling elements. Like the other “sibling” methods, this weeds out text and comment nodes.



426
427
428
429
430
# File 'lib/ext/hpricot/traverse.rb', line 426

def preceding_siblings() 
  sibs = parent.containers 
  si = sibs.index(self) 
  return Elements[*sibs[0...si]] 
end

#previous_siblingObject

Returns the container node neighboring this node to the north: just above it. By “container” node, I mean: this method does not find text nodes or comments or cdata or any of that. See Hpricot::Traverse#previous_node if you need to hunt out all kinds of nodes.



418
419
420
421
422
# File 'lib/ext/hpricot/traverse.rb', line 418

def previous_sibling
  sib = parent.containers
  x = sib.index(self) - 1
  sib[x] if sib and x >= 0
end

#replace_child(old, new) ⇒ Object

Replace old, a child of the current node, with new node.



466
467
468
469
# File 'lib/ext/hpricot/traverse.rb', line 466

def replace_child(old, new)
  reparent new
  children[children.index(old), 1] = [*new]
end

#siblings_at(*pos) ⇒ Object

Puts together an array of neighboring sibling elements based on their proximity to this element.

This method accepts ranges and sets of numbers.

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

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



451
452
453
454
455
456
457
458
459
460
461
462
463
# File 'lib/ext/hpricot/traverse.rb', line 451

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

#traverse_text_internal(&block) ⇒ Object



687
688
689
# File 'lib/ext/hpricot/traverse.rb', line 687

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