@@ -274,20 +274,33 @@ impl Parser {
274274 Ok ( Node :: Django ( DjangoNode :: Variable { bits, filters } ) )
275275 }
276276
277- fn parse_html_tag_open ( & mut self , s : & str ) -> Result < Node , ParserError > {
277+ fn parse_tag_open ( & mut self , s : & str , token_type : & TokenType ) -> Result < Node , ParserError > {
278278 let mut parts = s. split_whitespace ( ) ;
279279
280- let tag_name = parts
281- . next ( )
282- . ok_or ( ParserError :: Ast ( AstError :: EmptyTag ) ) ?
283- . to_string ( ) ;
284-
285- if tag_name. to_lowercase ( ) == "!doctype" {
286- return Ok ( Node :: Html ( HtmlNode :: Doctype ( "!DOCTYPE html" . to_string ( ) ) ) ) ;
287- }
280+ // Only HTML needs the tag name from the input
281+ let tag_name = match token_type {
282+ TokenType :: HtmlTagOpen ( _) => {
283+ let name = parts
284+ . next ( )
285+ . ok_or ( ParserError :: Ast ( AstError :: EmptyTag ) ) ?
286+ . to_string ( ) ;
287+ if name. to_lowercase ( ) == "!doctype" {
288+ return Ok ( Node :: Html ( HtmlNode :: Doctype ( "!DOCTYPE html" . to_string ( ) ) ) ) ;
289+ }
290+ name
291+ }
292+ TokenType :: ScriptTagOpen ( _) => {
293+ parts. next ( ) ; // Skip the tag name
294+ "script" . to_string ( )
295+ }
296+ TokenType :: StyleTagOpen ( _) => {
297+ parts. next ( ) ; // Skip the tag name
298+ "style" . to_string ( )
299+ }
300+ _ => return Err ( ParserError :: invalid_tag ( "Unknown tag type" . to_string ( ) ) ) ,
301+ } ;
288302
289303 let mut attributes = BTreeMap :: new ( ) ;
290-
291304 for attr in parts {
292305 if let Some ( ( key, value) ) = parse_attribute ( attr) ? {
293306 attributes. insert ( key, value) ;
@@ -314,16 +327,37 @@ impl Parser {
314327 }
315328
316329 if !found_closing_tag {
317- return Err ( ParserError :: Ast ( AstError :: UnclosedTag (
318- tag_name. to_string ( ) ,
319- ) ) ) ;
320- }
330+ return Err ( ParserError :: Ast ( AstError :: UnclosedTag ( tag_name. clone ( ) ) ) ) ;
331+ }
332+
333+ Ok ( match token_type {
334+ TokenType :: HtmlTagOpen ( _) => Node :: Html ( HtmlNode :: Element {
335+ tag_name,
336+ attributes,
337+ children,
338+ } ) ,
339+ TokenType :: ScriptTagOpen ( _) => Node :: Script ( ScriptNode :: Element {
340+ attributes,
341+ children,
342+ } ) ,
343+ TokenType :: StyleTagOpen ( _) => Node :: Style ( StyleNode :: Element {
344+ attributes,
345+ children,
346+ } ) ,
347+ _ => return Err ( ParserError :: invalid_tag ( "Unknown tag type" . to_string ( ) ) ) ,
348+ } )
349+ }
321350
322- Ok ( Node :: Html ( HtmlNode :: Element {
323- tag_name,
324- attributes,
325- children,
326- } ) )
351+ fn parse_html_tag_open ( & mut self , s : & str ) -> Result < Node , ParserError > {
352+ self . parse_tag_open ( s, & TokenType :: HtmlTagOpen ( String :: new ( ) ) )
353+ }
354+
355+ fn parse_script_tag_open ( & mut self , s : & str ) -> Result < Node , ParserError > {
356+ self . parse_tag_open ( s, & TokenType :: ScriptTagOpen ( String :: new ( ) ) )
357+ }
358+
359+ fn parse_style_tag_open ( & mut self , s : & str ) -> Result < Node , ParserError > {
360+ self . parse_tag_open ( s, & TokenType :: StyleTagOpen ( String :: new ( ) ) )
327361 }
328362
329363 fn parse_html_tag_void ( & mut self , s : & str ) -> Result < Node , ParserError > {
@@ -348,93 +382,6 @@ impl Parser {
348382 } ) )
349383 }
350384
351- fn parse_script_tag_open ( & mut self , s : & str ) -> Result < Node , ParserError > {
352- let mut parts = s. split_whitespace ( ) ;
353-
354- let _tag_name = parts
355- . next ( )
356- . ok_or ( ParserError :: Ast ( AstError :: EmptyTag ) ) ?
357- . to_string ( ) ;
358-
359- let mut attributes = BTreeMap :: new ( ) ;
360-
361- for attr in parts {
362- if let Some ( ( key, value) ) = parse_attribute ( attr) ? {
363- attributes. insert ( key, value) ;
364- }
365- }
366-
367- let mut children = Vec :: new ( ) ;
368- let mut found_closing_tag = false ;
369-
370- while !self . is_at_end ( ) {
371- match self . next_node ( ) {
372- Ok ( node) => {
373- children. push ( node) ;
374- }
375- Err ( ParserError :: ErrorSignal ( Signal :: ClosingTagFound ( tag) ) ) => {
376- if tag == "script" {
377- found_closing_tag = true ;
378- self . consume ( ) ?;
379- break ;
380- }
381- }
382- Err ( e) => return Err ( e) ,
383- }
384- }
385-
386- if !found_closing_tag {
387- return Err ( ParserError :: Ast ( AstError :: UnclosedTag (
388- "script" . to_string ( ) ,
389- ) ) ) ;
390- }
391-
392- Ok ( Node :: Script ( ScriptNode :: Element {
393- attributes,
394- children,
395- } ) )
396- }
397-
398- fn parse_style_tag_open ( & mut self , s : & str ) -> Result < Node , ParserError > {
399- let parts = s. split_whitespace ( ) ;
400-
401- let mut attributes = BTreeMap :: new ( ) ;
402-
403- for attr in parts {
404- if let Some ( ( key, value) ) = parse_attribute ( attr) ? {
405- attributes. insert ( key, value) ;
406- }
407- }
408-
409- let mut children = Vec :: new ( ) ;
410- let mut found_closing_tag = false ;
411-
412- while !self . is_at_end ( ) {
413- match self . next_node ( ) {
414- Ok ( node) => {
415- children. push ( node) ;
416- }
417- Err ( ParserError :: ErrorSignal ( Signal :: ClosingTagFound ( tag) ) ) => {
418- if tag == "style" {
419- found_closing_tag = true ;
420- self . consume ( ) ?;
421- break ;
422- }
423- }
424- Err ( e) => return Err ( e) ,
425- }
426- }
427-
428- if !found_closing_tag {
429- return Err ( ParserError :: Ast ( AstError :: UnclosedTag ( "style" . to_string ( ) ) ) ) ;
430- }
431-
432- Ok ( Node :: Style ( StyleNode :: Element {
433- attributes,
434- children,
435- } ) )
436- }
437-
438385 fn peek ( & self ) -> Result < Token , ParserError > {
439386 self . peek_at ( 0 )
440387 }
0 commit comments