@@ -76,7 +76,7 @@ def __init__(self, tree, pseudo_element=None):
7676 #: +-------------------------+----------------+--------------------------------+
7777 #: | Invalid pseudo-class | ``li:marker`` | ``None`` |
7878 #: +-------------------------+----------------+--------------------------------+
79- #: | Functinal | ``a::foo(2)`` | ``FunctionalPseudoElement(…)`` |
79+ #: | Functional | ``a::foo(2)`` | ``FunctionalPseudoElement(…)`` |
8080 #: +-------------------------+----------------+--------------------------------+
8181 #:
8282 #: .. _Lists3: http://www.w3.org/TR/2011/WD-css3-lists-20110524/#marker-pseudoelement
@@ -92,6 +92,20 @@ def __repr__(self):
9292 return '%s[%r%s]' % (
9393 self .__class__ .__name__ , self .parsed_tree , pseudo_element )
9494
95+ def canonical (self ):
96+ """Return a CSS representation for this selector (a string)
97+ """
98+ if isinstance (self .pseudo_element , FunctionalPseudoElement ):
99+ pseudo_element = '::%s' % self .pseudo_element .canonical ()
100+ elif self .pseudo_element :
101+ pseudo_element = '::%s' % self .pseudo_element
102+ else :
103+ pseudo_element = ''
104+ res = '%s%s' % (self .parsed_tree .canonical (), pseudo_element )
105+ if len (res ) > 1 :
106+ res = res .lstrip ('*' )
107+ return res
108+
95109 def specificity (self ):
96110 """Return the specificity_ of this selector as a tuple of 3 integers.
97111
@@ -116,6 +130,9 @@ def __repr__(self):
116130 return '%s[%r.%s]' % (
117131 self .__class__ .__name__ , self .selector , self .class_name )
118132
133+ def canonical (self ):
134+ return '%s.%s' % (self .selector .canonical (), self .class_name )
135+
119136 def specificity (self ):
120137 a , b , c = self .selector .specificity ()
121138 b += 1
@@ -151,6 +168,10 @@ def __repr__(self):
151168 def argument_types (self ):
152169 return [token .type for token in self .arguments ]
153170
171+ def canonical (self ):
172+ args = '' .join (token .css () for token in self .arguments )
173+ return '%s(%s)' % (self .name , args )
174+
154175 def specificity (self ):
155176 a , b , c = self .selector .specificity ()
156177 b += 1
@@ -174,6 +195,10 @@ def __repr__(self):
174195 def argument_types (self ):
175196 return [token .type for token in self .arguments ]
176197
198+ def canonical (self ):
199+ args = '' .join (token .css () for token in self .arguments )
200+ return '%s:%s(%s)' % (self .selector .canonical (), self .name , args )
201+
177202 def specificity (self ):
178203 a , b , c = self .selector .specificity ()
179204 b += 1
@@ -192,6 +217,9 @@ def __repr__(self):
192217 return '%s[%r:%s]' % (
193218 self .__class__ .__name__ , self .selector , self .ident )
194219
220+ def canonical (self ):
221+ return '%s:%s' % (self .selector .canonical (), self .ident )
222+
195223 def specificity (self ):
196224 a , b , c = self .selector .specificity ()
197225 b += 1
@@ -210,6 +238,12 @@ def __repr__(self):
210238 return '%s[%r:not(%r)]' % (
211239 self .__class__ .__name__ , self .selector , self .subselector )
212240
241+ def canonical (self ):
242+ subsel = self .subselector .canonical ()
243+ if len (subsel ) > 1 :
244+ subsel = subsel .lstrip ('*' )
245+ return '%s:not(%s)' % (self .selector .canonical (), subsel )
246+
213247 def specificity (self ):
214248 a1 , b1 , c1 = self .selector .specificity ()
215249 a2 , b2 , c2 = self .subselector .specificity ()
@@ -238,7 +272,20 @@ def __repr__(self):
238272 else :
239273 return '%s[%r[%s %s %r]]' % (
240274 self .__class__ .__name__ , self .selector , attrib ,
241- self .operator , self .value )
275+ self .operator , self .value .value )
276+
277+ def canonical (self ):
278+ if self .namespace :
279+ attrib = '%s|%s' % (self .namespace , self .attrib )
280+ else :
281+ attrib = self .attrib
282+
283+ if self .operator == 'exists' :
284+ op = attrib
285+ else :
286+ op = '%s%s%s' % (attrib , self .operator , self .value .css ())
287+
288+ return '%s[%s]' % (self .selector .canonical (), op )
242289
243290 def specificity (self ):
244291 a , b , c = self .selector .specificity ()
@@ -258,10 +305,13 @@ def __init__(self, namespace=None, element=None):
258305 self .element = element
259306
260307 def __repr__ (self ):
308+ return '%s[%s]' % (self .__class__ .__name__ , self .canonical ())
309+
310+ def canonical (self ):
261311 element = self .element or '*'
262312 if self .namespace :
263313 element = '%s|%s' % (self .namespace , element )
264- return '%s[%s]' % ( self . __class__ . __name__ , element )
314+ return element
265315
266316 def specificity (self ):
267317 if self .element :
@@ -282,6 +332,9 @@ def __repr__(self):
282332 return '%s[%r#%s]' % (
283333 self .__class__ .__name__ , self .selector , self .id )
284334
335+ def canonical (self ):
336+ return '%s#%s' % (self .selector .canonical (), self .id )
337+
285338 def specificity (self ):
286339 a , b , c = self .selector .specificity ()
287340 a += 1
@@ -303,6 +356,13 @@ def __repr__(self):
303356 return '%s[%r %s %r]' % (
304357 self .__class__ .__name__ , self .selector , comb , self .subselector )
305358
359+ def canonical (self ):
360+ subsel = self .subselector .canonical ()
361+ if len (subsel ) > 1 :
362+ subsel = subsel .lstrip ('*' )
363+ return '%s %s %s' % (
364+ self .selector .canonical (), self .combinator , subsel )
365+
306366 def specificity (self ):
307367 a1 , b1 , c1 = self .selector .specificity ()
308368 a2 , b2 , c2 = self .subselector .specificity ()
@@ -546,7 +606,7 @@ def parse_attrib(selector, stream):
546606 if next != ('DELIM' , ']' ):
547607 raise SelectorSyntaxError (
548608 "Expected ']', got %s" % (next ,))
549- return Attrib (selector , namespace , attrib , op , value . value )
609+ return Attrib (selector , namespace , attrib , op , value )
550610
551611
552612def parse_series (tokens ):
@@ -601,6 +661,12 @@ def is_delim(self, *values):
601661 type = property (operator .itemgetter (0 ))
602662 value = property (operator .itemgetter (1 ))
603663
664+ def css (self ):
665+ if self .type == 'STRING' :
666+ return repr (self .value )
667+ else :
668+ return self .value
669+
604670
605671class EOFToken (Token ):
606672 def __new__ (cls , pos ):
0 commit comments