diff --git a/lib/oga/css/parser.y b/lib/oga/css/parser.y index be33899..b7504e2 100644 --- a/lib/oga/css/parser.y +++ b/lib/oga/css/parser.y @@ -23,7 +23,15 @@ rule selectors : selector - | selectors_ { s(:path, *val[0]) } + { + # a single "+ y" selector + if val[0].is_a?(Array) + return s(:path, *val[0]) + else + return val[0] + end + } + | selectors_ { s(:path, *val[0].flatten) } ; selectors_ @@ -41,9 +49,21 @@ rule ; axis - : T_GREATER axis_selector { s(:axis, 'child', val[1]) } - | T_TILDE axis_selector { s(:axis, 'following', val[1]) } - | T_PLUS axis_selector { s(:axis, 'following-direct', val[1]) } + : T_GREATER axis_selector + { + s(:axis, 'child', val[1]) + } + | T_TILDE axis_selector + { + s(:axis, 'following-sibling', val[1]) + } + | T_PLUS axis_selector + { + [ + s(:axis, 'following-sibling', s(:test, nil, '*', s(:int, 1))), + s(:axis, 'self', val[1]) + ] + } ; axis_selector diff --git a/spec/oga/css/parser/axes_spec.rb b/spec/oga/css/parser/axes_spec.rb index b5703aa..80f655b 100644 --- a/spec/oga/css/parser/axes_spec.rb +++ b/spec/oga/css/parser/axes_spec.rb @@ -18,23 +18,20 @@ describe Oga::CSS::Parser do example 'parse an > axis followed by an element with a class' do parse_css('x > foo.bar').should == parse_xpath( - 'descendant-or-self::x/foo[contains(concat(" ", @class, " "), "bar")]' + 'descendant-or-self::x/foo[contains(concat(" ", @class, " "), " bar ")]' ) end example 'parse the + axis' do - parse_css('x + y').should == s( - :following_direct, - s(:test, nil, 'x'), - s(:test, nil, 'y') + parse_css('x + y').should == parse_xpath( + 'descendant-or-self::x/following-sibling::*[1]/self::y' ) end example 'parse the + axis called on another + axis' do - parse_css('a + b + c').should == s( - :following_direct, - s(:following_direct, s(:test, nil, 'a'), s(:test, nil, 'b')), - s(:test, nil, 'c') + parse_css('a + b + c').should == parse_xpath( + 'descendant-or-self::a/following-sibling::*[1]/self::b/' \ + 'following-sibling::*[1]/self::c' ) end @@ -46,7 +43,7 @@ describe Oga::CSS::Parser do example 'parse the ~ axis followed by another node test' do parse_css('x ~ y z').should == parse_xpath( - 'descendant-or-self::x/following-sibling::y/z' + 'descendant-or-self::x/following-sibling::y/descendant-or-self::z' ) end @@ -55,21 +52,5 @@ describe Oga::CSS::Parser do 'descendant-or-self::a/following-sibling::b/following-sibling::c' ) end - - example 'parse a pseudo class followed by the ~ axis' do - parse_css('x:root ~ a').should == s( - :following, - s(:pseudo, s(:test, nil, 'x'), 'root'), - s(:test, nil, 'a') - ) - end - - example 'parse the ~ axis followed by a pseudo class' do - parse_css('a ~ x:root').should == s( - :following, - s(:test, nil, 'a'), - s(:pseudo, s(:test, nil, 'x'), 'root') - ) - end end end