@@ -255,8 +255,9 @@ class Relation(object):
255255 Represents selector:has(subselector)
256256 """
257257
258- def __init__ (self , selector , subselector ):
258+ def __init__ (self , selector , combinator , subselector ):
259259 self .selector = selector
260+ self .combinator = combinator
260261 self .subselector = subselector
261262
262263 def __repr__ (self ):
@@ -267,19 +268,20 @@ def __repr__(self):
267268 )
268269
269270 def canonical (self ):
270- if not self .subselector :
271- subsel = "*"
272- else :
271+ try :
273272 subsel = self .subselector [0 ].canonical ()
273+ except TypeError :
274+ subsel = self .subselector .canonical ()
274275 if len (subsel ) > 1 :
275276 subsel = subsel .lstrip ("*" )
276277 return "%s:has(%s)" % (self .selector .canonical (), subsel )
277278
278279 def specificity (self ):
279280 a1 , b1 , c1 = self .selector .specificity ()
280- a2 = b2 = c2 = 0
281- if self .subselector :
281+ try :
282282 a2 , b2 , c2 = self .subselector [- 1 ].specificity ()
283+ except TypeError :
284+ a2 , b2 , c2 = self .subselector .specificity ()
283285 return a1 + a2 , b1 + b2 , c1 + c2
284286
285287
@@ -600,8 +602,8 @@ def parse_simple_selector(stream, inside_negation=False):
600602 raise SelectorSyntaxError ("Expected ')', got %s" % (next ,))
601603 result = Negation (result , argument )
602604 elif ident .lower () == "has" :
603- arguments = parse_relative_selector (stream )
604- result = Relation (result , arguments )
605+ combinator , arguments = parse_relative_selector (stream )
606+ result = Relation (result , combinator , arguments )
605607 elif ident .lower () in ("matches" , "is" ):
606608 selectors = parse_simple_selector_arguments (stream )
607609 result = Matching (result , selectors )
@@ -631,23 +633,27 @@ def parse_arguments(stream):
631633
632634
633635def parse_relative_selector (stream ):
634- arguments = []
635636 stream .skip_whitespace ()
637+ subselector = ""
636638 next = stream .next ()
639+
637640 if next in [("DELIM" , "+" ), ("DELIM" , "-" ), ("DELIM" , ">" ), ("DELIM" , "~" )]:
638- arguments .append (next )
639- elif next .type in ("IDENT" , "STRING" , "NUMBER" ):
640- arguments .append (Element (element = next .value ))
641- while 1 :
641+ combinator = next
642642 stream .skip_whitespace ()
643643 next = stream .next ()
644- if next .type in ("IDENT" , "STRING" , "NUMBER" ):
645- arguments .append (Element (element = next .value ))
644+ else :
645+ combinator = Token ("DELIM" , " " , pos = 0 )
646+
647+ while 1 :
648+ if next .type in ("IDENT" , "STRING" , "NUMBER" ) or next in [("DELIM" , "." ), ("DELIM" , "*" )]:
649+ subselector += next .value
646650 elif next == ('DELIM' , ')' ):
647- return arguments
651+ result = parse (subselector )
652+ return combinator , result [0 ]
648653 else :
649654 raise SelectorSyntaxError (
650655 "Expected an argument, got %s" % (next ,))
656+ next = stream .next ()
651657
652658
653659def parse_simple_selector_arguments (stream ):
0 commit comments