@@ -749,6 +749,15 @@ def startTagScript(self, token):
749749 self .parser .originalPhase = self .parser .phase
750750 self .parser .phase = self .parser .phases ["text" ]
751751
752+ def startTagTemplate (self , token ):
753+ # WHATWG "in head": insert the element, then switch to "in template".
754+ # Template contents stay as ordinary children (html5lib does not yet
755+ # implement the template content document fragment).
756+ self .tree .insertElement (token )
757+ self .parser .framesetOK = False
758+ self .parser .originalPhase = self .parser .phase
759+ self .parser .phase = self .parser .phases ["inTemplate" ]
760+
752761 def startTagOther (self , token ):
753762 self .anythingElse ()
754763 return token
@@ -774,6 +783,7 @@ def anythingElse(self):
774783 (("noframes" , "style" ), startTagNoFramesStyle ),
775784 ("noscript" , startTagNoscript ),
776785 ("script" , startTagScript ),
786+ ("template" , startTagTemplate ),
777787 (("base" , "basefont" , "bgsound" , "command" , "link" ),
778788 startTagBaseLinkCommand ),
779789 ("meta" , startTagMeta ),
@@ -909,7 +919,7 @@ def anythingElse(self):
909919 ("body" , startTagBody ),
910920 ("frameset" , startTagFrameset ),
911921 (("base" , "basefont" , "bgsound" , "link" , "meta" , "noframes" , "script" ,
912- "style" , "title" ),
922+ "style" , "template" , " title" ),
913923 startTagFromHead ),
914924 ("head" , startTagHead )
915925 ])
@@ -919,6 +929,69 @@ def anythingElse(self):
919929 endTagHandler .default = endTagOther
920930
921931
932+ class InTemplatePhase (Phase ):
933+ """Simplified "in template" insertion mode.
934+
935+ Places template contents as ordinary children of the ``template`` element.
936+ Full WHATWG template content fragments and the stack of template insertion
937+ modes are not implemented.
938+ """
939+ __slots__ = tuple ()
940+
941+ def processEOF (self ):
942+ self .parser .parseError ("eof-in-template" )
943+ self .endTagTemplate (impliedTagToken ("template" ))
944+ return True
945+
946+ def processComment (self , token ):
947+ self .tree .insertComment (token )
948+
949+ def processCharacters (self , token ):
950+ self .tree .insertText (token ["data" ])
951+
952+ def processSpaceCharacters (self , token ):
953+ self .tree .insertText (token ["data" ])
954+
955+ def startTagTemplate (self , token ):
956+ return self .parser .phases ["inHead" ].processStartTag (token )
957+
958+ def startTagOther (self , token ):
959+ self .tree .insertElement (token )
960+
961+ def endTagTemplate (self , token ):
962+ for i , node in enumerate (reversed (self .tree .openElements )):
963+ if node .name == "template" :
964+ del self .tree .openElements [- (i + 1 ):]
965+ break
966+ else :
967+ self .parser .parseError ("unexpected-end-tag" , {"name" : "template" })
968+ return
969+ self .parser .phase = self .parser .originalPhase
970+
971+ def endTagOther (self , token ):
972+ # Pop a matching open element inside the template when present.
973+ for node in reversed (self .tree .openElements ):
974+ if node .name == "template" :
975+ self .parser .parseError ("unexpected-end-tag" , {"name" : token ["name" ]})
976+ return
977+ if node .name == token ["name" ]:
978+ while self .tree .openElements [- 1 ].name != token ["name" ]:
979+ self .tree .openElements .pop ()
980+ self .tree .openElements .pop ()
981+ return
982+ self .parser .parseError ("unexpected-end-tag" , {"name" : token ["name" ]})
983+
984+ startTagHandler = _utils .MethodDispatcher ([
985+ ("template" , startTagTemplate ),
986+ ])
987+ startTagHandler .default = startTagOther
988+
989+ endTagHandler = _utils .MethodDispatcher ([
990+ ("template" , endTagTemplate ),
991+ ])
992+ endTagHandler .default = endTagOther
993+
994+
922995class InBodyPhase (Phase ):
923996 # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody
924997 # the really-really-really-very crazy mode
@@ -1581,7 +1654,7 @@ def endTagOther(self, token):
15811654 startTagHandler = _utils .MethodDispatcher ([
15821655 ("html" , Phase .startTagHtml ),
15831656 (("base" , "basefont" , "bgsound" , "command" , "link" , "meta" ,
1584- "script" , "style" , "title" ),
1657+ "script" , "style" , "template" , " title" ),
15851658 startTagProcessInHead ),
15861659 ("body" , startTagBody ),
15871660 ("frameset" , startTagFrameset ),
@@ -2752,6 +2825,7 @@ def processEndTag(self, token):
27522825 "inHead" : InHeadPhase ,
27532826 "inHeadNoscript" : InHeadNoscriptPhase ,
27542827 "afterHead" : AfterHeadPhase ,
2828+ "inTemplate" : InTemplatePhase ,
27552829 "inBody" : InBodyPhase ,
27562830 "text" : TextPhase ,
27572831 "inTable" : InTablePhase ,
0 commit comments