diff --git a/lib/oga/css/parser.y b/lib/oga/css/parser.y
index b7f5e8f..09e5b56 100644
--- a/lib/oga/css/parser.y
+++ b/lib/oga/css/parser.y
@@ -515,7 +515,11 @@ end
# @return [AST::Node]
#
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
##
diff --git a/spec/oga/css/evaluator/pseudo_classes/first_of_type_spec.rb b/spec/oga/css/evaluator/pseudo_classes/first_of_type_spec.rb
index 8315926..e9bcdde 100644
--- a/spec/oga/css/evaluator/pseudo_classes/first_of_type_spec.rb
+++ b/spec/oga/css/evaluator/pseudo_classes/first_of_type_spec.rb
@@ -3,22 +3,25 @@ require 'spec_helper'
describe 'CSS selector evaluation' do
context ':first-of-type pseudo class' do
before do
- @document = parse('')
+ @document = parse(<<-EOF)
+
+ - foo
+ -
+
+ - bar
+ - baz
+
+
+
+ EOF
- @a1 = @document.children[0].children[0]
- @b1 = @document.children[0].children[1]
+ @dt1 = @document.at_xpath('dl/dt')
+ @dt2 = @document.at_xpath('dl/dd/dl/dt')
end
- example 'return a node set containing the first node' do
- evaluate_css(@document, 'root :first-of-type').should == node_set(@a1)
- end
-
- 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 node' do
- evaluate_css(@document, 'root b:first-of-type').should == node_set(@b1)
+ example 'return a node set containing all nodes' do
+ evaluate_css(@document, 'dl dt:first-of-type')
+ .should == node_set(@dt1, @dt2)
end
end
end
diff --git a/spec/oga/css/parser/pseudo_classes/first_of_type_spec.rb b/spec/oga/css/parser/pseudo_classes/first_of_type_spec.rb
index 5e903a8..ae88987 100644
--- a/spec/oga/css/parser/pseudo_classes/first_of_type_spec.rb
+++ b/spec/oga/css/parser/pseudo_classes/first_of_type_spec.rb
@@ -4,7 +4,13 @@ describe Oga::CSS::Parser do
context ':first-of-type pseudo class' do
example 'parse the :first-of-type pseudo class' do
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