Parsing support for nth-child(n+X)
This commit is contained in:
parent
8d8d74ec41
commit
0faceffacb
|
@ -274,11 +274,14 @@ rule
|
||||||
# n
|
# n
|
||||||
: T_NTH { s(:nth, s(:int, 1)) }
|
: T_NTH { s(:nth, s(:int, 1)) }
|
||||||
|
|
||||||
|
# n+2
|
||||||
|
| T_NTH integer { s(:nth, s(:int, 1), val[1]) }
|
||||||
|
|
||||||
# -n
|
# -n
|
||||||
| T_MINUS T_NTH { s(:nth, s(:int, 1)) }
|
| T_MINUS T_NTH { s(:nth, s(:int, 1)) }
|
||||||
|
|
||||||
# -n+2, -n-2
|
# -n+2, -n-2
|
||||||
| T_MINUS T_NTH integer { s(:nth, nil, val[2]) }
|
| T_MINUS T_NTH integer { s(:nth, s(:int, -1), val[2]) }
|
||||||
|
|
||||||
# 2n
|
# 2n
|
||||||
| integer T_NTH { s(:nth, val[0]) }
|
| integer T_NTH { s(:nth, val[0]) }
|
||||||
|
@ -406,27 +409,11 @@ end
|
||||||
else
|
else
|
||||||
step, offset = *arg
|
step, offset = *arg
|
||||||
before_count = s(:add, count_call, s(:int, 1))
|
before_count = s(:add, count_call, s(:int, 1))
|
||||||
|
compare = step_comparison(step)
|
||||||
if step and step.children[0] >= 0
|
|
||||||
compare = :gte
|
|
||||||
else
|
|
||||||
compare = :lte
|
|
||||||
end
|
|
||||||
|
|
||||||
# 2n+2, 2n-4, etc
|
# 2n+2, 2n-4, etc
|
||||||
if offset
|
if offset
|
||||||
# -2n
|
mod_val = step_modulo_value(step)
|
||||||
if step and non_positive_number?(step)
|
|
||||||
mod_val = s(:int, -step.children[0])
|
|
||||||
|
|
||||||
# 2n
|
|
||||||
elsif step
|
|
||||||
mod_val = step
|
|
||||||
|
|
||||||
else
|
|
||||||
mod_val = s(:int, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
node = s(
|
node = s(
|
||||||
:and,
|
:and,
|
||||||
s(compare, before_count, offset),
|
s(compare, before_count, offset),
|
||||||
|
@ -460,4 +447,30 @@ end
|
||||||
return node.children[0] <= 0
|
return node.children[0] <= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# @param [AST::Node] node
|
||||||
|
# @return [Symbol]
|
||||||
|
#
|
||||||
|
def step_comparison(node)
|
||||||
|
return node.children[0] >= 0 ? :gte : :lte
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# @param [AST::Node] node
|
||||||
|
# @return [AST::Node]
|
||||||
|
#
|
||||||
|
def step_modulo_value(step)
|
||||||
|
# -2n
|
||||||
|
if step and non_positive_number?(step)
|
||||||
|
mod_val = s(:int, -step.children[0])
|
||||||
|
|
||||||
|
# 2n
|
||||||
|
elsif step
|
||||||
|
mod_val = step
|
||||||
|
|
||||||
|
else
|
||||||
|
mod_val = s(:int, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# vim: set ft=racc:
|
# vim: set ft=racc:
|
||||||
|
|
|
@ -52,6 +52,13 @@ describe Oga::CSS::Parser do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
example 'parse the x:nth-child(n+5) pseudo class' do
|
||||||
|
parse_css('x:nth-child(n+5)').should == parse_xpath(
|
||||||
|
'descendant-or-self::x[(count(preceding-sibling::*) + 1) >= 5 ' \
|
||||||
|
'and (((count(preceding-sibling::*) + 1) - 5) mod 1) = 0]'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
example 'parse the x:nth-child(2n) pseudo class' do
|
example 'parse the x:nth-child(2n) pseudo class' do
|
||||||
parse_css('x:nth-child(2n)').should == parse_css('x:nth-child(even)')
|
parse_css('x:nth-child(2n)').should == parse_css('x:nth-child(even)')
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue