diff --git a/lib/oga/css/lexer.rl b/lib/oga/css/lexer.rl index 24d8512..1878391 100644 --- a/lib/oga/css/lexer.rl +++ b/lib/oga/css/lexer.rl @@ -239,12 +239,16 @@ module Oga pseudo_args := |* whitespace; - nth => { add_token(:T_NTH) }; - minus => { add_token(:T_MINUS) }; - odd => { add_token(:T_ODD) }; - even => { add_token(:T_EVEN) }; - integer => emit_integer; - rparen => emit_rparen; + # NOTE: the priorities here are put in place to ensure that rules such + # as `nth` take precedence over `identifier`. The highest number has + # the highest priority. + nth > 5 => { add_token(:T_NTH) }; + minus => { add_token(:T_MINUS) }; + odd > 4 => { add_token(:T_ODD) }; + even > 3 => { add_token(:T_EVEN) }; + integer > 2 => emit_integer; + rparen => emit_rparen; + identifier > 1 => emit_identifier; *|; # Predicates diff --git a/lib/oga/css/parser.y b/lib/oga/css/parser.y index 5379d15..43382ca 100644 --- a/lib/oga/css/parser.y +++ b/lib/oga/css/parser.y @@ -142,6 +142,7 @@ rule | odd | even | nth + | node_test ; odd diff --git a/spec/oga/css/lexer/pseudo_classes_spec.rb b/spec/oga/css/lexer/pseudo_classes_spec.rb index 772b976..c075588 100644 --- a/spec/oga/css/lexer/pseudo_classes_spec.rb +++ b/spec/oga/css/lexer/pseudo_classes_spec.rb @@ -116,5 +116,15 @@ describe Oga::CSS::Lexer do [:T_RPAREN, nil] ] end + + example 'lex the :lang(fr) pseudo class' do + lex_css(':lang(fr)').should == [ + [:T_COLON, nil], + [:T_IDENT, 'lang'], + [:T_LPAREN, nil], + [:T_IDENT, 'fr'], + [:T_RPAREN, nil] + ] + end end end diff --git a/spec/oga/css/parser/pseudo_classes_spec.rb b/spec/oga/css/parser/pseudo_classes_spec.rb index 0466b0b..b738993 100644 --- a/spec/oga/css/parser/pseudo_classes_spec.rb +++ b/spec/oga/css/parser/pseudo_classes_spec.rb @@ -107,5 +107,14 @@ describe Oga::CSS::Parser do s(:pseudo, 'focus', s(:test, nil, 'x')) ) end + + example 'parse a pseudo class with an identifier as the argument' do + parse_css('x:lang(fr)').should == s( + :pseudo, + 'lang', + s(:test, nil, 'x'), + s(:test, nil, 'fr') + ) + end end end