Changeset 106

Show
Ignore:
Timestamp:
01/31/2007 19:47:13 (22 months ago)
Author:
why
Message:
  • lib/hpricot/elements.rb: here we go. now support for a[text()="Click Me!"] and h3[text()*="space"] and the like.
Location:
trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/hpricot/elements.rb

    r105 r106  
    194194    end 
    195195 
    196     ATTR_RE = %r!\[ *(@)([a-zA-Z0-9\(\)_-]+) *([~\!\|\*$\^=]*) *'?"?([^'"]*)'?"? *\]!i 
     196    ATTR_RE = %r!\[ *(?:(@)([\w\(\)-]+)|([\w\(\)-]+\(\))) *([~\!\|\*$\^=]*) *'?"?([^'"]*)'?"? *\]!i 
    197197    BRACK_RE = %r!(\[) *([^\]]*) *\]!i 
    198198    FUNC_RE = %r!(:)?([a-zA-Z0-9\*_-]*)\( *[\"']?([^ \)]*?)['\"]? *\)! 
     
    217217                nodes, = Elements.filter(nodes, m[2], false) 
    218218            else 
    219                 meth = "filter[#{m[0]}]" 
     219                meth = "filter[#{m[0]}#{m[1]}]" 
    220220                if Traverse.method_defined? meth 
    221                     args = m[1..-1] 
     221                    args = m[2..-1] 
    222222                else 
    223                     meth = "filter[#{m[0]}#{m[1]}]" 
     223                    meth = "filter[#{m[0]}]" 
    224224                    if Traverse.method_defined? meth 
    225                         args = m[2..-1] 
     225                        args = m[1..-1] 
    226226                    end 
    227227                end 
     
    362362    end 
    363363 
    364     filter '@=' do |attr,val,i| 
    365       self.elem? and get_attribute(attr).to_s == val 
    366     end 
    367  
    368     filter '@!=' do |attr,val,i| 
    369       self.elem? and get_attribute(attr).to_s != val 
    370     end 
    371  
    372     filter '@~=' do |attr,val,i| 
    373       self.elem? and get_attribute(attr).to_s.split(/\s+/).include? val 
    374     end 
    375  
    376     filter '@|=' do |attr,val,i| 
    377       self.elem? and get_attribute(attr).to_s =~ /^#{Regexp::quote val}(-|$)/ 
    378     end 
    379  
    380     filter '@^=' do |attr,val,i| 
    381       self.elem? and get_attribute(attr).to_s.index(val) == 0 
    382     end 
    383  
    384     filter '@$=' do |attr,val,i| 
    385       self.elem? and get_attribute(attr).to_s =~ /#{Regexp::quote val}$/ 
    386     end 
    387  
    388     filter '@*=' do |attr,val,i| 
    389       if self.elem? 
    390         idx = get_attribute(attr).to_s.index(val) 
    391         idx >= 0 if idx 
    392       end 
     364    pred_procs = 
     365      {'text()' => proc { |ele, *_| ele.inner_text.strip }, 
     366       '@'      => proc { |ele, attr, *_| ele.get_attribute(attr).to_s if ele.elem? }} 
     367     
     368    oper_procs = 
     369      {'='      => proc { |a,b| a == b }, 
     370       '!='     => proc { |a,b| a != b }, 
     371       '~='     => proc { |a,b| a.split(/\s+/).include?(b) }, 
     372       '|='     => proc { |a,b| a =~ /^#{Regexp::quote b}(-|$)/ }, 
     373       '^='     => proc { |a,b| a.index(b) == 0 }, 
     374       '$='     => proc { |a,b| a =~ /#{Regexp::quote b}$/ }, 
     375       '*='     => proc { |a,b| idx = a.index(b) }} 
     376 
     377    pred_procs.each do |pred_n, pred_f| 
     378      oper_procs.each do |oper_n, oper_f| 
     379        filter "#{pred_n}#{oper_n}" do |*a| 
     380          qual = pred_f[self, *a] 
     381          oper_f[qual, a[-2]] if qual 
     382        end 
     383      end 
     384    end 
     385 
     386    filter 'text()' do |val,i| 
     387      !self.inner_text.strip.empty? 
    393388    end 
    394389 
  • trunk/test/test_parser.rb

    r99 r106  
    9090    assert_equal 1, @boingboing.search("//a[@name='027906']").length 
    9191    assert_equal 10, @boingboing.search("script comment()").length 
     92    assert_equal 3, @boingboing.search("a[text()*='Boing']").length 
     93    assert_equal 1, @boingboing.search("h3[text()='College kids reportedly taking more smart drugs']").length 
     94    assert_equal 0, @boingboing.search("h3[text()='College']").length 
     95    assert_equal 60, @boingboing.search("h3").length 
     96    assert_equal 59, @boingboing.search("h3[text()!='College kids reportedly taking more smart drugs']").length 
     97    assert_equal 17, @boingboing.search("h3[text()$='s']").length 
     98    assert_equal 128, @boingboing.search("p[text()]").length 
     99    assert_equal 211, @boingboing.search("p").length 
    92100  end 
    93101