@@ -182,12 +182,27 @@ class Function(object):
182
182
"""
183
183
Represents selector:name(expr)
184
184
"""
185
- def __init__ (self , selector , name , arguments ):
185
+
186
+ def __init__ (self , selector , name , arguments , of_type = None ):
186
187
self .selector = selector
187
188
self .name = ascii_lower (name )
188
189
self .arguments = arguments
189
190
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
+
190
197
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
+ )
191
206
return '%s[%r:%s(%r)]' % (
192
207
self .__class__ .__name__ , self .selector , self .name ,
193
208
[token .value for token in self .arguments ])
@@ -539,7 +554,8 @@ def parse_simple_selector(stream, inside_negation=False):
539
554
raise SelectorSyntaxError ("Expected ')', got %s" % (next ,))
540
555
result = Negation (result , argument )
541
556
else :
542
- result = Function (result , ident , parse_arguments (stream ))
557
+ arguments , of_type = parse_arguments (stream )
558
+ result = Function (result , ident , arguments , of_type )
543
559
else :
544
560
raise SelectorSyntaxError (
545
561
"Expected selector, got %s" % (peek ,))
@@ -554,16 +570,33 @@ def parse_arguments(stream):
554
570
while 1 :
555
571
stream .skip_whitespace ()
556
572
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
+ ]:
559
581
arguments .append (next )
560
582
elif next == ('DELIM' , ')' ):
561
- return arguments
583
+ return arguments , None
562
584
else :
563
585
raise SelectorSyntaxError (
564
586
"Expected an argument, got %s" % (next ,))
565
587
566
588
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
+
567
600
def parse_attrib (selector , stream ):
568
601
stream .skip_whitespace ()
569
602
attrib = stream .next_ident_or_star ()
@@ -620,6 +653,7 @@ def parse_series(tokens):
620
653
for token in tokens :
621
654
if token .type == 'STRING' :
622
655
raise ValueError ('String tokens not allowed in series.' )
656
+
623
657
s = '' .join (token .value for token in tokens ).strip ()
624
658
if s == 'odd' :
625
659
return 2 , 1
@@ -630,7 +664,7 @@ def parse_series(tokens):
630
664
if 'n' not in s :
631
665
# Just b
632
666
return 0 , int (s )
633
- a , b = s .split ('n' , 1 )
667
+ a , b = s .split ("n" , 1 )
634
668
if not a :
635
669
a = 1
636
670
elif a == '-' or a == '+' :
@@ -641,6 +675,7 @@ def parse_series(tokens):
641
675
b = 0
642
676
else :
643
677
b = int (b )
678
+
644
679
return a , b
645
680
646
681
0 commit comments