Parsing support for :nth-of-type()

This commit is contained in:
Yorick Peterse 2014-11-02 19:29:39 +01:00
parent 0faceffacb
commit ab8b451dc3
2 changed files with 145 additions and 0 deletions

View File

@ -429,6 +429,40 @@ end
return node
end
##
# Generates the AST for the `nth-of-type` pseudo class.
#
# @param [AST::Node] arg
# @return [AST::Node]
#
def on_pseudo_class_nth_of_type(arg)
position_call = s(:call, 'position')
# literal 2, 4, etc
if int_node?(arg)
node = s(:eq, position_call, arg)
else
step, offset = *arg
compare = step_comparison(step)
# 2n+2, 2n-4, etc
if offset
mod_val = step_modulo_value(step)
node = s(
:and,
s(compare, position_call, offset),
s(:eq, s(:mod, s(:sub, position_call, offset), mod_val), s(:int, 0))
)
# 2n, n, -2n
else
node = s(:eq, s(:mod, position_call, step), s(:int, 0))
end
end
return node
end
private
##

View File

@ -0,0 +1,111 @@
require 'spec_helper'
describe Oga::CSS::Parser do
context ':nth-of-type pseudo class' do
example 'parse the :nth-of-type(1) pseudo class' do
parse_css(':nth-of-type(1)').should == parse_xpath(
'descendant-or-self::*[position() = 1]'
)
end
example 'parse the :nth-of-type(2n) pseudo class' do
parse_css(':nth-of-type(2n)').should == parse_xpath(
'descendant-or-self::*[(position() mod 2) = 0]'
)
end
example 'parse the :nth-of-type(3n) pseudo class' do
parse_css(':nth-of-type(3n)').should == parse_xpath(
'descendant-or-self::*[(position() mod 3) = 0]'
)
end
example 'parse the :nth-of-type(2n+5) pseudo class' do
parse_css(':nth-of-type(2n+5)').should == parse_xpath(
'descendant-or-self::*[(position() >= 5) ' \
'and (((position() - 5) mod 2) = 0)]'
)
end
example 'parse the :nth-of-type(3n+5) pseudo class' do
parse_css(':nth-of-type(3n+5)').should == parse_xpath(
'descendant-or-self::*[(position() >= 5) ' \
'and (((position() - 5) mod 3) = 0)]'
)
end
example 'parse the :nth-of-type(2n-5) pseudo class' do
parse_css(':nth-of-type(2n-5)').should == parse_xpath(
'descendant-or-self::*[(position() >= 1) ' \
'and (((position() - 1) mod 2) = 0)]'
)
end
example 'parse the :nth-of-type(2n-6) pseudo class' do
parse_css(':nth-of-type(2n-6)').should == parse_xpath(
'descendant-or-self::*[(position() >= 2) ' \
'and (((position() - 2) mod 2) = 0)]'
)
end
example 'parse the :nth-of-type(-2n+5) pseudo class' do
parse_css(':nth-of-type(-2n+5)').should == parse_xpath(
'descendant-or-self::*[(position() <= 5) ' \
'and ((position() - 5) mod 2) = 0]'
)
end
example 'parse the :nth-of-type(-2n-5) pseudo class' do
parse_css(':nth-of-type(-2n-5)').should == parse_xpath(
'descendant-or-self::*[(position() <= -1) ' \
'and ((position() - -1) mod 2) = 0]'
)
end
example 'parse the :nth-of-type(-2n-6) pseudo class' do
parse_css(':nth-of-type(-2n-6)').should == parse_xpath(
'descendant-or-self::*[(position() <= -2) ' \
'and ((position() - -2) mod 2) = 0]'
)
end
example 'parse the :nth-of-type(even) pseudo class' do
parse_css(':nth-of-type(even)').should == parse_xpath(
'descendant-or-self::*[(position() mod 2) = 0]'
)
end
example 'parse the :nth-of-type(odd) pseudo class' do
parse_css(':nth-of-type(odd)').should == parse_xpath(
'descendant-or-self::*[(position() >= 1) ' \
'and (((position() - 1) mod 2) = 0)]'
)
end
example 'parse the :nth-of-type(n) pseudo class' do
parse_css(':nth-of-type(n)').should == parse_xpath(
'descendant-or-self::*[(position() mod 1) =0]'
)
end
example 'parse the :nth-of-type(n+5) pseudo class' do
parse_css(':nth-of-type(n+5)').should == parse_xpath(
'descendant-or-self::*[position() >= 5 ' \
'and ((position() - 5) mod 1) = 0]'
)
end
example 'parse the :nth-of-type(-n) pseudo class' do
parse_css(':nth-of-type(-n)').should == parse_xpath(
'descendant-or-self::*[(position() mod 1) = 0]'
)
end
example 'parse the :nth-of-type(-n+5) pseudo class' do
parse_css(':nth-of-type(-n+5)').should == parse_xpath(
'descendant-or-self::*[(position() <= 5) ' \
'and ((position() - 5) mod 1) = 0]'
)
end
end
end