@@ -182,12 +182,27 @@ class Function(object):
182182 """
183183 Represents selector:name(expr)
184184 """
185- def __init__ (self , selector , name , arguments ):
185+
186+ def __init__ (self , selector , name , arguments , of_type = None ):
186187 self .selector = selector
187188 self .name = ascii_lower (name )
188189 self .arguments = arguments
189190
191+ # for css4 :nth-child(An+B of Subselector)
192+ try :
193+ self .of_type = of_type [0 ]
194+ except (IndexError , TypeError ):
195+ self .of_type = None
196+
190197 def __repr__ (self ):
198+ if self .of_type :
199+ return "%s[%r:%s(%r of %s)]" % (
200+ self .__class__ .__name__ ,
201+ self .selector ,
202+ self .name ,
203+ [token .value for token in self .arguments ],
204+ self .of_type .__repr__ (),
205+ )
191206 return '%s[%r:%s(%r)]' % (
192207 self .__class__ .__name__ , self .selector , self .name ,
193208 [token .value for token in self .arguments ])
@@ -539,7 +554,8 @@ def parse_simple_selector(stream, inside_negation=False):
539554 raise SelectorSyntaxError ("Expected ')', got %s" % (next ,))
540555 result = Negation (result , argument )
541556 else :
542- result = Function (result , ident , parse_arguments (stream ))
557+ arguments , of_type = parse_arguments (stream )
558+ result = Function (result , ident , arguments , of_type )
543559 else :
544560 raise SelectorSyntaxError (
545561 "Expected selector, got %s" % (peek ,))
@@ -554,16 +570,33 @@ def parse_arguments(stream):
554570 while 1 :
555571 stream .skip_whitespace ()
556572 next = stream .next ()
557- if next .type in ('IDENT' , 'STRING' , 'NUMBER' ) or next in [
558- ('DELIM' , '+' ), ('DELIM' , '-' )]:
573+ if next == ("IDENT" , "of" ):
574+ stream .skip_whitespace ()
575+ of_type = parse_of_type (stream )
576+ return arguments , of_type
577+ elif next .type in ("IDENT" , "STRING" , "NUMBER" ) or next in [
578+ ("DELIM" , "+" ),
579+ ("DELIM" , "-" ),
580+ ]:
559581 arguments .append (next )
560582 elif next == ('DELIM' , ')' ):
561- return arguments
583+ return arguments , None
562584 else :
563585 raise SelectorSyntaxError (
564586 "Expected an argument, got %s" % (next ,))
565587
566588
589+ def parse_of_type (stream ):
590+ subselector = ""
591+ while 1 :
592+ next = stream .next ()
593+ if next == ("DELIM" , ")" ):
594+ break
595+ subselector += next .value
596+ result = parse (subselector )
597+ return result
598+
599+
567600def parse_attrib (selector , stream ):
568601 stream .skip_whitespace ()
569602 attrib = stream .next_ident_or_star ()
@@ -620,6 +653,7 @@ def parse_series(tokens):
620653 for token in tokens :
621654 if token .type == 'STRING' :
622655 raise ValueError ('String tokens not allowed in series.' )
656+
623657 s = '' .join (token .value for token in tokens ).strip ()
624658 if s == 'odd' :
625659 return 2 , 1
@@ -630,7 +664,7 @@ def parse_series(tokens):
630664 if 'n' not in s :
631665 # Just b
632666 return 0 , int (s )
633- a , b = s .split ('n' , 1 )
667+ a , b = s .split ("n" , 1 )
634668 if not a :
635669 a = 1
636670 elif a == '-' or a == '+' :
@@ -641,6 +675,7 @@ def parse_series(tokens):
641675 b = 0
642676 else :
643677 b = int (b )
678+
644679 return a , b
645680
646681
0 commit comments