Fixed CSS evaluation of :first-of-type
The old XPath "position() = 1" would work in Nokogiri due to the way they retrieve descendants. In Oga however this would simply always return the first node. To fix this Oga now counts the amount of preceding siblings that match the same full name.
This commit is contained in:
parent
e3a26c5d15
commit
0128dc50ae
|
@ -515,7 +515,11 @@ end
|
||||||
# @return [AST::Node]
|
# @return [AST::Node]
|
||||||
#
|
#
|
||||||
def on_pseudo_class_first_of_type
|
def on_pseudo_class_first_of_type
|
||||||
return s(:eq, s(:call, 'position'), s(:int, 1))
|
return s(
|
||||||
|
:eq,
|
||||||
|
s(:call, 'count', s(:axis, 'preceding-sibling', s(:call, 'name'))),
|
||||||
|
s(:int, 0)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
@ -3,22 +3,25 @@ require 'spec_helper'
|
||||||
describe 'CSS selector evaluation' do
|
describe 'CSS selector evaluation' do
|
||||||
context ':first-of-type pseudo class' do
|
context ':first-of-type pseudo class' do
|
||||||
before do
|
before do
|
||||||
@document = parse('<root><a /><b /></root>')
|
@document = parse(<<-EOF)
|
||||||
|
<dl>
|
||||||
|
<dt>foo</dt>
|
||||||
|
<dd>
|
||||||
|
<dl>
|
||||||
|
<dt>bar</dt>
|
||||||
|
<dd>baz</dd>
|
||||||
|
</dl>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
EOF
|
||||||
|
|
||||||
@a1 = @document.children[0].children[0]
|
@dt1 = @document.at_xpath('dl/dt')
|
||||||
@b1 = @document.children[0].children[1]
|
@dt2 = @document.at_xpath('dl/dd/dl/dt')
|
||||||
end
|
end
|
||||||
|
|
||||||
example 'return a node set containing the first node' do
|
example 'return a node set containing all <dt> nodes' do
|
||||||
evaluate_css(@document, 'root :first-of-type').should == node_set(@a1)
|
evaluate_css(@document, 'dl dt:first-of-type')
|
||||||
end
|
.should == node_set(@dt1, @dt2)
|
||||||
|
|
||||||
example 'return a node set containing the first node with a node test' do
|
|
||||||
evaluate_css(@document, 'root a:first-of-type').should == node_set(@a1)
|
|
||||||
end
|
|
||||||
|
|
||||||
example 'return a node set containing the first <b> node' do
|
|
||||||
evaluate_css(@document, 'root b:first-of-type').should == node_set(@b1)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,13 @@ describe Oga::CSS::Parser do
|
||||||
context ':first-of-type pseudo class' do
|
context ':first-of-type pseudo class' do
|
||||||
example 'parse the :first-of-type pseudo class' do
|
example 'parse the :first-of-type pseudo class' do
|
||||||
parse_css(':first-of-type').should == parse_xpath(
|
parse_css(':first-of-type').should == parse_xpath(
|
||||||
'descendant::*[position() = 1]'
|
'descendant::*[count(preceding-sibling::name()) = 0]'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'parse the a:first-of-type pseudo class' do
|
||||||
|
parse_css('a:first-of-type').should == parse_xpath(
|
||||||
|
'descendant::a[count(preceding-sibling::name()) = 0]'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue