From a6b0bd96c8f25dbb0645a6d4b70e505c01bf79ce Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 7 Oct 2014 22:57:23 +0200 Subject: [PATCH] Support for parsing CSS class/ID selectors. --- lib/oga/css/parser.y | 23 ++++++++++++++++++++++- spec/oga/css/parser/classes_spec.rb | 12 ++++++++++++ spec/oga/css/parser/ids_spec.rb | 12 ++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/oga/css/parser.y b/lib/oga/css/parser.y index c612752..c83bc09 100644 --- a/lib/oga/css/parser.y +++ b/lib/oga/css/parser.y @@ -6,13 +6,14 @@ class Oga::CSS::Parser token T_IDENT T_PIPE T_LBRACK T_RBRACK T_COLON T_SPACE T_LPAREN T_RPAREN T_MINUS token T_EQ T_SPACE_IN T_STARTS_WITH T_ENDS_WITH T_IN T_HYPHEN_IN token T_CHILD T_FOLLOWING T_FOLLOWING_DIRECT -token T_NTH T_INT T_STRING T_ODD T_EVEN +token T_NTH T_INT T_STRING T_ODD T_EVEN T_DOT T_HASH options no_result_var prechigh left T_COLON left T_CHILD T_FOLLOWING T_FOLLOWING_DIRECT + left T_DOT T_HASH preclow rule @@ -39,6 +40,8 @@ rule : node_test | axis | pseudo_class + | class + | id ; node_test @@ -66,6 +69,24 @@ rule | operator ; + class + : class_name { s(:class, val[0]) } + | path_member class_name { s(:class, val[1], val[0]) } + ; + + class_name + : T_DOT T_IDENT { val[1] } + ; + + id + : id_name { s(:id, val[0]) } + | path_member id_name { s(:id, val[1], val[0]) } + ; + + id_name + : T_HASH T_IDENT { val[1] } + ; + operator : op_members T_EQ op_members { s(:eq, val[0], val[2]) } | op_members T_SPACE_IN op_members { s(:space_in, val[0], val[2]) } diff --git a/spec/oga/css/parser/classes_spec.rb b/spec/oga/css/parser/classes_spec.rb index f726df1..bb362b6 100644 --- a/spec/oga/css/parser/classes_spec.rb +++ b/spec/oga/css/parser/classes_spec.rb @@ -17,5 +17,17 @@ describe Oga::CSS::Parser do example 'parse a selector using a class and an ID' do parse_css('#foo.bar').should == s(:class, 'bar', s(:id, 'foo')) end + + example 'parse a selector using a class and a pseudo class' do + parse_css('.foo:root').should == s(:pseudo, 'root', s(:class, 'foo')) + end + + example 'parse a selector using a pseudo class and a class' do + parse_css('x:root.foo').should == s( + :class, + 'foo', + s(:pseudo, 'root', s(:test, nil, 'x')) + ) + end end end diff --git a/spec/oga/css/parser/ids_spec.rb b/spec/oga/css/parser/ids_spec.rb index a783a14..aeb0744 100644 --- a/spec/oga/css/parser/ids_spec.rb +++ b/spec/oga/css/parser/ids_spec.rb @@ -13,5 +13,17 @@ describe Oga::CSS::Parser do example 'parse a selector using an ID and a class' do parse_css('.foo#bar').should == s(:id, 'bar', s(:class, 'foo')) end + + example 'parse a selector using an ID and a pseudo class' do + parse_css('#foo:root').should == s(:pseudo, 'root', s(:id, 'foo')) + end + + example 'parse a selector using a pseudo class and an ID' do + parse_css('x:root#foo').should == s( + :id, + 'foo', + s(:pseudo, 'root', s(:test, nil, 'x')) + ) + end end end