@@ -161,16 +161,18 @@ def __init__(self, name, arguments):
161161 self .arguments = arguments
162162
163163 def __repr__ (self ):
164- return '%s[::%s(%r)]' % (
165- self .__class__ .__name__ , self .name ,
166- [token .value for token in self .arguments ])
164+ return "%s[::%s(%r)]" % (
165+ self .__class__ .__name__ ,
166+ self .name ,
167+ [token .value for token in self .arguments [0 ]],
168+ )
167169
168170 def argument_types (self ):
169171 return [token .type for token in self .arguments ]
170172
171173 def canonical (self ):
172- args = '' .join (token .css () for token in self .arguments )
173- return ' %s(%s)' % (self .name , args )
174+ args = "" .join (token .css () for token in self .arguments [ 0 ] )
175+ return " %s(%s)" % (self .name , args )
174176
175177 def specificity (self ):
176178 a , b , c = self .selector .specificity ()
@@ -182,12 +184,27 @@ class Function(object):
182184 """
183185 Represents selector:name(expr)
184186 """
185- def __init__ (self , selector , name , arguments ):
187+
188+ def __init__ (self , selector , name , arguments , of_type = None ):
186189 self .selector = selector
187190 self .name = ascii_lower (name )
188191 self .arguments = arguments
189192
193+ # for css4 :nth-child(An+B of Subselector)
194+ try :
195+ self .of_type = of_type [0 ]
196+ except (IndexError , TypeError ):
197+ self .of_type = None
198+
190199 def __repr__ (self ):
200+ if self .of_type :
201+ return "%s[%r:%s(%r of %s)]" % (
202+ self .__class__ .__name__ ,
203+ self .selector ,
204+ self .name ,
205+ [token .value for token in self .arguments ],
206+ self .of_type .__repr__ (),
207+ )
191208 return '%s[%r:%s(%r)]' % (
192209 self .__class__ .__name__ , self .selector , self .name ,
193210 [token .value for token in self .arguments ])
@@ -539,7 +556,8 @@ def parse_simple_selector(stream, inside_negation=False):
539556 raise SelectorSyntaxError ("Expected ')', got %s" % (next ,))
540557 result = Negation (result , argument )
541558 else :
542- result = Function (result , ident , parse_arguments (stream ))
559+ arguments , of_type = parse_arguments (stream )
560+ result = Function (result , ident , arguments , of_type )
543561 else :
544562 raise SelectorSyntaxError (
545563 "Expected selector, got %s" % (peek ,))
@@ -554,16 +572,33 @@ def parse_arguments(stream):
554572 while 1 :
555573 stream .skip_whitespace ()
556574 next = stream .next ()
557- if next .type in ('IDENT' , 'STRING' , 'NUMBER' ) or next in [
558- ('DELIM' , '+' ), ('DELIM' , '-' )]:
575+ if next == ("IDENT" , "of" ):
576+ stream .skip_whitespace ()
577+ of_type = parse_of_type (stream )
578+ return arguments , of_type
579+ elif next .type in ("IDENT" , "STRING" , "NUMBER" ) or next in [
580+ ("DELIM" , "+" ),
581+ ("DELIM" , "-" ),
582+ ]:
559583 arguments .append (next )
560584 elif next == ('DELIM' , ')' ):
561- return arguments
585+ return arguments , None
562586 else :
563587 raise SelectorSyntaxError (
564588 "Expected an argument, got %s" % (next ,))
565589
566590
591+ def parse_of_type (stream ):
592+ subselector = ""
593+ while 1 :
594+ next = stream .next ()
595+ if next == ("DELIM" , ")" ):
596+ break
597+ subselector += next .value
598+ result = parse (subselector )
599+ return result
600+
601+
567602def parse_attrib (selector , stream ):
568603 stream .skip_whitespace ()
569604 attrib = stream .next_ident_or_star ()
@@ -620,6 +655,7 @@ def parse_series(tokens):
620655 for token in tokens :
621656 if token .type == 'STRING' :
622657 raise ValueError ('String tokens not allowed in series.' )
658+
623659 s = '' .join (token .value for token in tokens ).strip ()
624660 if s == 'odd' :
625661 return 2 , 1
@@ -630,7 +666,7 @@ def parse_series(tokens):
630666 if 'n' not in s :
631667 # Just b
632668 return 0 , int (s )
633- a , b = s .split ('n' , 1 )
669+ a , b = s .split ("n" , 1 )
634670 if not a :
635671 a = 1
636672 elif a == '-' or a == '+' :
@@ -641,6 +677,7 @@ def parse_series(tokens):
641677 b = 0
642678 else :
643679 b = int (b )
680+
644681 return a , b
645682
646683
0 commit comments