Changeset 150

Show
Ignore:
Timestamp:
06/05/2007 00:58:55 (18 months ago)
Author:
why
Message:
  • lib/hpricot/elements.rb: added block syntax to attr, new methods remove_attr and remove_class. Got rid of set, making it an alias for attr which does much more.
Location:
trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/README

    r104 r150  
    258258What measures does <tt>:xhtml_strict</tt> take? 
    259259 
    260  1. Shift elements into their proper containers just like <tt>:fixup_tags</tt>. 
     260 1. Shift elements into their proper containers just like :fixup_tags. 
    261261 2. Remove unknown elements. 
    262262 3. Remove unknown attributes. 
     
    271271<tt>br</tt> tag is found, XML mode won't try to turn that into an empty element. 
    272272 
     273XML mode also doesn't downcase the tags and attributes for you.  So pay attention 
     274to case, friends. 
     275 
    273276The primary way to use Hpricot's XML mode is to call the Hpricot.XML method: 
    274277 
  • trunk/lib/hpricot/elements.rb

    r145 r150  
    173173    end 
    174174 
    175     def attr key, value = nil 
    176       if value 
     175    # Gets and sets attributes on all matched elements. 
     176    # 
     177    # Pass in a +key+ on its own and this method will return the string value 
     178    # assigned to that attribute for the first elements.  Or +nil+ if the  
     179    # attribute isn't found. 
     180    # 
     181    #   doc.search("a").attr("href") 
     182    #     #=> "http://hacketyhack.net/" 
     183    # 
     184    # Or, pass in a +key+ and +value+.  This will set an attribute for all 
     185    # matched elements. 
     186    # 
     187    #   doc.search("p").attr("class", "basic") 
     188    #  
     189    # You may also use a Hash to set a series of attributes: 
     190    # 
     191    #   (doc/"a").attr(:class => "basic", :href => "http://hackety.org/") 
     192    #  
     193    # Lastly, a block can be used to rewrite an attribute based on the element 
     194    # it belongs to.  The block will pass in an element.  Return from the block 
     195    # the new value of the attribute. 
     196    # 
     197    #   records.attr("href") { |e| e['href'] + "#top" } 
     198    # 
     199    # This example adds a <tt>#top</tt> anchor to each link. 
     200    # 
     201    def attr key, value = nil, &blk 
     202      if value or blk 
    177203        each do |el| 
    178           el.set_attribute(key, value) 
     204          el.set_attribute(key, value || blk[el]) 
    179205        end 
    180206        return self       
     
    187213      end 
    188214    end 
     215    alias_method :set, :attr 
    189216   
     217    # Adds the class to all matched elements. 
     218    # 
     219    #   (doc/"p").add_class("bacon") 
     220    # 
     221    # Now all paragraphs will have class="bacon". 
    190222    def add_class class_name 
    191223      each do |el| 
     
    197229    end 
    198230 
    199     # Sets an attribute for all elements in this list.  You may use 
    200     # a simple pair (<em>attribute name</em>, <em>attribute value</em>): 
    201     # 
    202     #   doc.search('p').set(:class, 'outline') 
    203     # 
    204     # Or, use a hash of pairs: 
    205     # 
    206     #   doc.search('div#sidebar').set(:class => 'outline', :id => 'topbar') 
    207     # 
    208     def set(k, v = nil) 
    209       case k 
    210       when Hash 
    211         each do |node| 
    212           k.each { |a,b| node.set_attribute(a, b) } 
    213         end 
    214       else 
    215         each do |node| 
    216           node.set_attribute(k, v) 
    217         end 
    218       end 
     231    # Remove an attribute from each of the matched elements. 
     232    # 
     233    #   (doc/"input").remove_attr("disabled") 
     234    # 
     235    def remove_attr name 
     236      each do |el| 
     237        next unless el.respond_to? :remove_attribute 
     238        el.remove_attribute(name) 
     239      end 
     240      self       
     241    end 
     242 
     243    # Removes a class from all matched elements. 
     244    # 
     245    #   (doc/"span").remove_class("lightgrey") 
     246    # 
     247    # Or, to remove all classes: 
     248    # 
     249    #   (doc/"span").remove_class 
     250    #  
     251    def remove_class name = nil 
     252      each do |el| 
     253        next unless el.respond_to? :get_attribute 
     254        if name 
     255          classes = el.get_attribute('class').to_s.split(" ") 
     256          el.set_attribute('class', (classes - [name]).uniq.join(" ")) 
     257        else 
     258          el.remove_attribute("class") 
     259        end 
     260      end 
     261      self       
    219262    end 
    220263 
  • trunk/test/test_alter.rb

    r145 r150  
    3838    all_ps = (@basic/"p").attr("title", "Some Title") 
    3939    all_as = (@basic/"a").attr("href", "http://my_new_href.com") 
     40    all_lb = (@basic/"link").attr("href") { |e| e.name } 
    4041    assert_changed(@basic, "p", all_ps) {|p| p.attributes["title"] == "Some Title"} 
    4142    assert_changed(@basic, "a", all_as) {|a| a.attributes["href"] == "http://my_new_href.com"} 
     43    assert_changed(@basic, "link", all_lb) {|a| a.attributes["href"] == "link" } 
    4244  end 
    4345   
     46  def test_remove_attr 
     47    all_rl = (@basic/"link").remove_attr("href") 
     48    assert_changed(@basic, "link", all_rl) { |link| link['href'].nil? } 
     49  end 
     50 
     51  def test_remove_class 
     52    all_c1 = (@basic/"p[@class*='last']").remove_class("last") 
     53    assert_changed(@basic, "p[@class*='last']", all_c1) { |p| p['class'] == 'final' } 
     54  end 
     55 
     56  def test_remove_all_classes 
     57    all_c2 = (@basic/"p[@class]").remove_class 
     58    assert_changed(@basic, "p[@class]", all_c2) { |p| p['class'].nil? } 
     59  end 
     60 
    4461  def assert_changed original, selector, set, &block 
    4562    assert set.all?(&block)