Support for parsing CSS axes.

This commit is contained in:
Yorick Peterse 2014-10-23 00:42:45 +02:00
parent 9955f61bcb
commit 7ee7f25239
2 changed files with 31 additions and 30 deletions

View File

@ -23,7 +23,15 @@ rule
selectors selectors
: selector : 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_ selectors_
@ -41,9 +49,21 @@ rule
; ;
axis axis
: T_GREATER axis_selector { s(:axis, 'child', val[1]) } : T_GREATER axis_selector
| T_TILDE axis_selector { s(:axis, 'following', val[1]) } {
| T_PLUS axis_selector { s(:axis, 'following-direct', val[1]) } 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 axis_selector

View File

@ -18,23 +18,20 @@ describe Oga::CSS::Parser do
example 'parse an > axis followed by an element with a class' do example 'parse an > axis followed by an element with a class' do
parse_css('x > foo.bar').should == parse_xpath( 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 end
example 'parse the + axis' do example 'parse the + axis' do
parse_css('x + y').should == s( parse_css('x + y').should == parse_xpath(
:following_direct, 'descendant-or-self::x/following-sibling::*[1]/self::y'
s(:test, nil, 'x'),
s(:test, nil, 'y')
) )
end end
example 'parse the + axis called on another + axis' do example 'parse the + axis called on another + axis' do
parse_css('a + b + c').should == s( parse_css('a + b + c').should == parse_xpath(
:following_direct, 'descendant-or-self::a/following-sibling::*[1]/self::b/' \
s(:following_direct, s(:test, nil, 'a'), s(:test, nil, 'b')), 'following-sibling::*[1]/self::c'
s(:test, nil, 'c')
) )
end end
@ -46,7 +43,7 @@ describe Oga::CSS::Parser do
example 'parse the ~ axis followed by another node test' do example 'parse the ~ axis followed by another node test' do
parse_css('x ~ y z').should == parse_xpath( 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 end
@ -55,21 +52,5 @@ describe Oga::CSS::Parser do
'descendant-or-self::a/following-sibling::b/following-sibling::c' 'descendant-or-self::a/following-sibling::b/following-sibling::c'
) )
end 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
end end