Skip to content

Commit

Permalink
fixing psuedo selectors and element selectors inside a not() function.
Browse files Browse the repository at this point in the history
…closes #205
  • Loading branch information
tenderlove committed Feb 14, 2010
1 parent 7e38028 commit 746d086
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rdoc
Expand Up @@ -22,6 +22,7 @@
* XML::Node#namespace= takes nil as a parameter
* XML::Node#xpath returns things other than NodeSet objects. GH #208
* XSLT::StyleSheet#transform accepts hashes for parameters. GH #223
* Psuedo selectors inside not() work. GH #205

=== 1.4.1 / 2009/12/10

Expand Down
4 changes: 3 additions & 1 deletion lib/nokogiri/css/parser.y
Expand Up @@ -222,7 +222,9 @@ rule
}
;
negation_arg
: hcap_1toN
: element_name
| element_name hcap_1toN
| hcap_1toN
;
end

Expand Down
11 changes: 8 additions & 3 deletions lib/nokogiri/css/xpath_visitor.rb
Expand Up @@ -40,7 +40,12 @@ def visit_function node
end

def visit_not node
'not(' + node.value.first.accept(self) + ')'
child = node.value.first
if :ELEMENT_NAME == child.type
"not(self::#{child.accept(self)})"
else
"not(#{child.accept(self)})"
end
end

def visit_preceding_selector node
Expand Down Expand Up @@ -100,8 +105,8 @@ def visit_pseudo_class node
return self.send(msg, node) if self.respond_to?(msg)

case node.value.first
when "first" then "position() = 1"
when "last" then "position() = last()"
when "first", "first-child" then "position() = 1"
when "last", "last-child" then "position() = last()"
when "first-of-type" then "position() = 1"
when "last-of-type" then "position() = last()"
when "only-of-type" then "last() = 1"
Expand Down
9 changes: 9 additions & 0 deletions test/css/test_xpath_visitor.rb
Expand Up @@ -8,6 +8,15 @@ def setup
@parser = Nokogiri::CSS::Parser.new
end

def test_not_simple_selector
assert_xpath('//ol/*[not(self::li)]', @parser.parse('ol > *:not(li)'))
end

def test_not_last_child
assert_xpath('//ol/*[not(position() = last())]',
@parser.parse('ol > *:not(:last-child)'))
end

def test_function_calls_allow_at_params
assert_xpath("//a[foo(., @href)]", @parser.parse('a:foo(@href)'))
assert_xpath("//a[foo(., @a, b)]", @parser.parse('a:foo(@a, b)'))
Expand Down

0 comments on commit 746d086

Please sign in to comment.