@@ -335,97 +335,6 @@ def checkStartTagUnknownAttributes(self, token):
335335"datavars" : {"tagName" :name ,
336336"attributeName" :attrName }}
337337
338- ##########################################################################
339- # Attribute validation
340- ##########################################################################
341-
342- def checkAttributeValues (self ,token ):
343- tagName = token .get ("name" ,"" )
344- fakeToken = {"tagName" :tagName .capitalize ()}
345- for attrName ,attrValue in token .get ("data" , []):
346- attrName = attrName .lower ()
347- fakeToken ["attributeName" ]= attrName .capitalize ()
348- method = getattr (self ,"validateAttributeValue%(tagName)s%(attributeName)s" % fakeToken ,None )
349- if method :
350- for t in method (token ,tagName ,attrName ,attrValue )or []:yield t
351- else :
352- method = getattr (self ,"validateAttributeValue%(attributeName)s" % fakeToken ,None )
353- if method :
354- for t in method (token ,tagName ,attrName ,attrValue )or []:yield t
355-
356- def validateAttributeValueClass (self ,token ,tagName ,attrName ,attrValue ):
357- for t in self .checkTokenList (tagName ,attrName ,attrValue )or []:
358- yield t
359- yield {"type" :"ParseError" ,
360- "data" :"invalid-attribute-value" ,
361- "datavars" : {"tagName" :tagName ,
362- "attributeName" :attrName }}
363-
364- def validateAttributeValueContenteditable (self ,token ,tagName ,attrName ,attrValue ):
365- for t in self .checkEnumeratedValue (token ,tagName ,attrName ,attrValue ,frozenset (('true' ,'false' ,'' )))or []:yield t
366-
367- def validateAttributeValueDir (self ,token ,tagName ,attrName ,attrValue ):
368- for t in self .checkEnumeratedValue (token ,tagName ,attrName ,attrValue ,frozenset (('ltr' ,'rtl' )))or []:yield t
369-
370- def validateAttributeValueDraggable (self ,token ,tagName ,attrName ,attrValue ):
371- for t in self .checkEnumeratedValue (token ,tagName ,attrName ,attrValue ,frozenset (('true' ,'false' )))or []:yield t
372-
373- def validateAttributeValueIrrelevant (self ,token ,tagName ,attrName ,attrValue ):
374- for t in self .checkBooleanValue (token ,tagName ,attrName ,attrValue )or []:yield t
375-
376- def validateAttributeValueLang (self ,token ,tagName ,attrName ,attrValue ):
377- if not attrValue :return # blank is OK
378- if not iso639codes .isValidLangCode (attrValue ):
379- yield {"type" :"ParseError" ,
380- "data" :"invalid-lang-code" ,
381- "datavars" : {"tagName" :tagName ,
382- "attributeName" :attrName ,
383- "attributeValue" :attrValue }}
384-
385- def validateAttributeValueContextmenu (self ,token ,tagName ,attrName ,attrValue ):
386- for t in self .checkIDValue (token ,tagName ,attrName ,attrValue )or []:yield t
387- self .thingsThatPointToAnID .append (token )
388-
389- def validateAttributeValueId (self ,token ,tagName ,attrName ,attrValue ):
390- # This method has side effects. It adds 'token' to the list of
391- # things that define an ID (self.thingsThatDefineAnID) so that we can
392- # later check 1) whether an ID is duplicated, and 2) whether all the
393- # things that point to something else by ID (like <label for> or
394- # <span contextmenu>) point to an ID that actually exists somewhere.
395- for t in self .checkIDValue (token ,tagName ,attrName ,attrValue )or []:yield t
396- if not attrValue :return
397- if attrValue in self .IDsWeHaveKnownAndLoved :
398- yield {"type" :"ParseError" ,
399- "data" :"duplicate-id" ,
400- "datavars" : {"tagName" :tagName }}
401- self .IDsWeHaveKnownAndLoved .append (attrValue )
402- self .thingsThatDefineAnID .append (token )
403-
404- def validateAttributeValueTabindex (self ,token ,tagName ,attrName ,attrValue ):
405- for t in self .checkIntegerValue (token ,tagName ,attrName ,attrValue )or []:yield t
406-
407- def validateAttributeValueRef (self ,token ,tagName ,attrName ,attrValue ):
408- # XXX
409- pass
410-
411- def validateAttributeValueTemplate (self ,token ,tagName ,attrName ,attrValue ):
412- # XXX
413- pass
414-
415- def validateAttributeValueHtmlXmlns (self ,token ,tagName ,attrName ,attrValue ):
416- if attrValue != "http://www.w3.org/1999/xhtml" :
417- yield {"type" :"ParseError" ,
418- "data" :"invalid-root-namespace" ,
419- "datavars" : {"tagName" :tagName ,
420- "attributeName" :attrName }}
421-
422- def validateAttributeValueBaseHref (self ,token ,tagName ,attrName ,attrValue ):
423- # XXX
424- pass
425-
426- def validateAttributeValueBaseTarget (self ,token ,tagName ,attrName ,attrValue ):
427- for t in self .checkBrowsingContext (token ,tagName ,attrName ,attrValue )or []:yield t
428-
429338##########################################################################
430339# Attribute validation helpers
431340##########################################################################
@@ -552,6 +461,95 @@ def checkBrowsingContext(self, token, tagName, attrName, attrValue):
552461"datavars" : {"tagName" :tagName ,
553462"attributeName" :attrName }}
554463
464+ ##########################################################################
465+ # Attribute validation
466+ ##########################################################################
467+
468+ def checkAttributeValues (self ,token ):
469+ tagName = token .get ("name" ,"" )
470+ fakeToken = {"tagName" :tagName .capitalize ()}
471+ for attrName ,attrValue in token .get ("data" , []):
472+ attrName = attrName .lower ()
473+ fakeToken ["attributeName" ]= attrName .capitalize ()
474+ method = getattr (self ,"validateAttributeValue%(tagName)s%(attributeName)s" % fakeToken ,None )
475+ if method :
476+ for t in method (token ,tagName ,attrName ,attrValue )or []:yield t
477+ else :
478+ method = getattr (self ,"validateAttributeValue%(attributeName)s" % fakeToken ,None )
479+ if method :
480+ for t in method (token ,tagName ,attrName ,attrValue )or []:yield t
481+
482+ def validateAttributeValueClass (self ,token ,tagName ,attrName ,attrValue ):
483+ for t in self .checkTokenList (tagName ,attrName ,attrValue )or []:
484+ yield t
485+ yield {"type" :"ParseError" ,
486+ "data" :"invalid-attribute-value" ,
487+ "datavars" : {"tagName" :tagName ,
488+ "attributeName" :attrName }}
489+
490+ def validateAttributeValueContenteditable (self ,token ,tagName ,attrName ,attrValue ):
491+ for t in self .checkEnumeratedValue (token ,tagName ,attrName ,attrValue ,frozenset (('true' ,'false' ,'' )))or []:yield t
492+
493+ def validateAttributeValueDir (self ,token ,tagName ,attrName ,attrValue ):
494+ for t in self .checkEnumeratedValue (token ,tagName ,attrName ,attrValue ,frozenset (('ltr' ,'rtl' )))or []:yield t
495+
496+ def validateAttributeValueDraggable (self ,token ,tagName ,attrName ,attrValue ):
497+ for t in self .checkEnumeratedValue (token ,tagName ,attrName ,attrValue ,frozenset (('true' ,'false' )))or []:yield t
498+
499+ def validateAttributeValueIrrelevant (self ,token ,tagName ,attrName ,attrValue ):
500+ for t in self .checkBooleanValue (token ,tagName ,attrName ,attrValue )or []:yield t
501+
502+ def validateAttributeValueLang (self ,token ,tagName ,attrName ,attrValue ):
503+ if not attrValue :return # blank is OK
504+ if not iso639codes .isValidLangCode (attrValue ):
505+ yield {"type" :"ParseError" ,
506+ "data" :"invalid-lang-code" ,
507+ "datavars" : {"tagName" :tagName ,
508+ "attributeName" :attrName ,
509+ "attributeValue" :attrValue }}
510+
511+ def validateAttributeValueContextmenu (self ,token ,tagName ,attrName ,attrValue ):
512+ for t in self .checkIDValue (token ,tagName ,attrName ,attrValue )or []:yield t
513+ self .thingsThatPointToAnID .append (token )
514+
515+ def validateAttributeValueId (self ,token ,tagName ,attrName ,attrValue ):
516+ # This method has side effects. It adds 'token' to the list of
517+ # things that define an ID (self.thingsThatDefineAnID) so that we can
518+ # later check 1) whether an ID is duplicated, and 2) whether all the
519+ # things that point to something else by ID (like <label for> or
520+ # <span contextmenu>) point to an ID that actually exists somewhere.
521+ for t in self .checkIDValue (token ,tagName ,attrName ,attrValue )or []:yield t
522+ if not attrValue :return
523+ if attrValue in self .IDsWeHaveKnownAndLoved :
524+ yield {"type" :"ParseError" ,
525+ "data" :"duplicate-id" ,
526+ "datavars" : {"tagName" :tagName }}
527+ self .IDsWeHaveKnownAndLoved .append (attrValue )
528+ self .thingsThatDefineAnID .append (token )
529+
530+ validateAttributeValueTabindex = checkIntegerValue
531+
532+ def validateAttributeValueRef (self ,token ,tagName ,attrName ,attrValue ):
533+ # XXX
534+ pass
535+
536+ def validateAttributeValueTemplate (self ,token ,tagName ,attrName ,attrValue ):
537+ # XXX
538+ pass
539+
540+ def validateAttributeValueHtmlXmlns (self ,token ,tagName ,attrName ,attrValue ):
541+ if attrValue != "http://www.w3.org/1999/xhtml" :
542+ yield {"type" :"ParseError" ,
543+ "data" :"invalid-root-namespace" ,
544+ "datavars" : {"tagName" :tagName ,
545+ "attributeName" :attrName }}
546+
547+ def validateAttributeValueBaseHref (self ,token ,tagName ,attrName ,attrValue ):
548+ # XXX
549+ pass
550+
551+ validateAttributeValueBaseTarget = checkBrowsingContext
552+
555553##########################################################################
556554# Whole document validation (IDs, etc.)
557555##########################################################################