@@ -63,17 +63,17 @@ pub struct HtmlParser<'a> {
6363impl < ' a > HtmlParser < ' a > {
6464 /// Creates a new parser.
6565 pub fn new ( allocator : & ' a Allocator , source : & ' a str , url : & str ) -> Self {
66- Self :: new_internal ( allocator, source, url, false , false , None )
66+ Self :: new_internal ( allocator, source, url, false , false , None , true , true , None )
6767 }
6868
6969 /// Creates a new parser with selectorless mode enabled.
7070 pub fn with_selectorless ( allocator : & ' a Allocator , source : & ' a str , url : & str ) -> Self {
71- Self :: new_internal ( allocator, source, url, true , false , None )
71+ Self :: new_internal ( allocator, source, url, true , false , None , true , true , None )
7272 }
7373
7474 /// Creates a new parser with expansion forms (ICU messages) enabled.
7575 pub fn with_expansion_forms ( allocator : & ' a Allocator , source : & ' a str , url : & str ) -> Self {
76- Self :: new_internal ( allocator, source, url, false , true , None )
76+ Self :: new_internal ( allocator, source, url, false , true , None , true , true , None )
7777 }
7878
7979 /// Creates a new parser with expansion forms and leading trivia chars enabled.
@@ -83,7 +83,17 @@ impl<'a> HtmlParser<'a> {
8383 url : & str ,
8484 leading_trivia_chars : std:: vec:: Vec < char > ,
8585 ) -> Self {
86- Self :: new_internal ( allocator, source, url, false , true , Some ( leading_trivia_chars) )
86+ Self :: new_internal (
87+ allocator,
88+ source,
89+ url,
90+ false ,
91+ true ,
92+ Some ( leading_trivia_chars) ,
93+ true ,
94+ true ,
95+ None ,
96+ )
8797 }
8898
8999 /// Creates a new parser with the given template options.
@@ -103,6 +113,9 @@ impl<'a> HtmlParser<'a> {
103113 options. enable_selectorless ,
104114 options. tokenize_expansion_forms ,
105115 options. leading_trivia_chars . clone ( ) ,
116+ options. enable_block_syntax ,
117+ options. enable_let_syntax ,
118+ options. interpolation . as_ref ( ) . map ( |( s, e) | ( s. as_str ( ) , e. as_str ( ) ) ) ,
106119 )
107120 }
108121
@@ -114,15 +127,24 @@ impl<'a> HtmlParser<'a> {
114127 selectorless : bool ,
115128 expansion_forms : bool ,
116129 leading_trivia_chars : Option < std:: vec:: Vec < char > > ,
130+ tokenize_blocks : bool ,
131+ tokenize_let : bool ,
132+ interpolation : Option < ( & str , & str ) > ,
117133 ) -> Self {
118134 let mut lexer = HtmlLexer :: new ( source)
119135 . with_selectorless ( selectorless)
120- . with_expansion_forms ( expansion_forms) ;
136+ . with_expansion_forms ( expansion_forms)
137+ . with_blocks ( tokenize_blocks)
138+ . with_let ( tokenize_let) ;
121139
122140 if let Some ( chars) = leading_trivia_chars {
123141 lexer = lexer. with_leading_trivia_chars ( chars) ;
124142 }
125143
144+ if let Some ( ( start, end) ) = interpolation {
145+ lexer = lexer. with_interpolation ( start, end) ;
146+ }
147+
126148 let result = lexer. tokenize ( ) ;
127149 let source_file = Arc :: new ( ParseSourceFile :: new ( source. to_string ( ) , url. to_string ( ) ) ) ;
128150
@@ -208,6 +230,8 @@ impl<'a> HtmlParser<'a> {
208230 & mut self . elements [ idx] ,
209231 HtmlElement {
210232 name : Atom :: from ( "" ) ,
233+ component_prefix : None ,
234+ component_tag_name : None ,
211235 attrs : Vec :: new_in ( self . allocator ) ,
212236 directives : Vec :: new_in ( self . allocator ) ,
213237 children : Vec :: new_in ( self . allocator ) ,
@@ -335,6 +359,8 @@ impl<'a> HtmlParser<'a> {
335359 & mut self . elements [ idx] ,
336360 HtmlElement {
337361 name : Atom :: from ( "" ) ,
362+ component_prefix : None ,
363+ component_tag_name : None ,
338364 attrs : Vec :: new_in ( self . allocator ) ,
339365 directives : Vec :: new_in ( self . allocator ) ,
340366 children : Vec :: new_in ( self . allocator ) ,
@@ -376,6 +402,8 @@ impl<'a> HtmlParser<'a> {
376402 & mut self . elements [ match_elem_idx] ,
377403 HtmlElement {
378404 name : Atom :: from ( "" ) ,
405+ component_prefix : None ,
406+ component_tag_name : None ,
379407 attrs : Vec :: new_in ( self . allocator ) ,
380408 directives : Vec :: new_in ( self . allocator ) ,
381409 children : Vec :: new_in ( self . allocator ) ,
@@ -521,11 +549,20 @@ impl<'a> HtmlParser<'a> {
521549 let start = start_token. start ;
522550 // TagOpenStart has parts [prefix, name]
523551 // ComponentOpenStart has parts [component_name, prefix, tag_name]
524- let ( tag_name, local_name, has_ns_prefix) =
552+ let ( tag_name, local_name, has_ns_prefix, component_prefix , component_tag_name ) =
525553 if start_token. token_type == HtmlTokenType :: ComponentOpenStart {
526- // For components, use the component name (first part)
527- let name = start_token. value ( ) . to_string ( ) ;
528- ( name. clone ( ) , name, false )
554+ // For components, extract all three parts:
555+ // parts[0] = component_name, parts[1] = prefix, parts[2] = tag_name
556+ let component_name = start_token. parts . first ( ) . cloned ( ) . unwrap_or_default ( ) ;
557+ let prefix = start_token. parts . get ( 1 ) . cloned ( ) . unwrap_or_default ( ) ;
558+ let raw_tag_name = start_token. parts . get ( 2 ) . cloned ( ) . unwrap_or_default ( ) ;
559+
560+ // Store prefix and tag_name for HtmlElement
561+ let prefix_opt = if prefix. is_empty ( ) { None } else { Some ( prefix. clone ( ) ) } ;
562+ let tag_opt =
563+ if raw_tag_name. is_empty ( ) { None } else { Some ( raw_tag_name. clone ( ) ) } ;
564+
565+ ( component_name. clone ( ) , component_name, false , prefix_opt, tag_opt)
529566 } else {
530567 // For regular tags, include the namespace prefix if present
531568 // Angular uses :prefix:name format for namespaced elements
@@ -534,7 +571,7 @@ impl<'a> HtmlParser<'a> {
534571 let has_prefix = !prefix. is_empty ( ) ;
535572 let full_name =
536573 if has_prefix { format ! ( ":{}:{}" , prefix, name) } else { name. to_string ( ) } ;
537- ( full_name, name. to_string ( ) , has_prefix)
574+ ( full_name, name. to_string ( ) , has_prefix, None , None )
538575 } ;
539576
540577 // Check if we need to auto-close the current element (HTML5 optional end tags)
@@ -596,6 +633,8 @@ impl<'a> HtmlParser<'a> {
596633
597634 let element = HtmlElement {
598635 name : Atom :: from_in ( tag_name. clone ( ) , self . allocator ) ,
636+ component_prefix : component_prefix. map ( |p| Atom :: from_in ( p, self . allocator ) ) ,
637+ component_tag_name : component_tag_name. map ( |t| Atom :: from_in ( t, self . allocator ) ) ,
599638 attrs,
600639 directives,
601640 children : Vec :: new_in ( self . allocator ) ,
@@ -1071,6 +1110,8 @@ impl<'a> HtmlParser<'a> {
10711110 // Note: is_self_closing is false because this is an incomplete tag, not explicitly self-closing
10721111 let element = HtmlElement {
10731112 name : Atom :: from_in ( tag_name. clone ( ) , self . allocator ) ,
1113+ component_prefix : None ,
1114+ component_tag_name : None ,
10741115 attrs : Vec :: new_in ( self . allocator ) ,
10751116 directives : Vec :: new_in ( self . allocator ) ,
10761117 children : Vec :: new_in ( self . allocator ) ,
0 commit comments