@@ -247,6 +247,7 @@ fn is_valid_for_html_tag_name(c: char, is_empty: bool) -> bool {
247
247
}
248
248
249
249
/// Parse html tags to ensure they are well-formed
250
+ #[ derive( Debug , Clone ) ]
250
251
struct TagParser {
251
252
tags : Vec < ( String , Range < usize > ) > ,
252
253
/// Name of the tag that is being parsed, if we are within a tag.
@@ -347,9 +348,8 @@ impl TagParser {
347
348
None if self . tag_name . is_empty ( ) => ( prev_pos, '\0' ) ,
348
349
None => break ,
349
350
} ;
350
- dbg ! ( pos, c, & self . in_attrs, & self . tag_name) ;
351
351
prev_pos = pos;
352
- if ! self . in_attrs && c == '/' && self . tag_name . is_empty ( ) {
352
+ if c == '/' && self . tag_name . is_empty ( ) {
353
353
// Checking if this is a closing tag (like `</a>` for `<a>`).
354
354
self . is_closing = true ;
355
355
} else if !self . in_attrs && is_valid_for_html_tag_name ( c, self . tag_name . is_empty ( ) ) {
@@ -364,6 +364,7 @@ impl TagParser {
364
364
r. end += 1 ;
365
365
}
366
366
if self . is_closing {
367
+ assert ! ( self . quote. is_none( ) && self . quote_pos. is_none( ) && !self . after_eq, "inconsistent state for closing tag: {self:?}" ) ;
367
368
// In case we have "</div >" or even "</div >".
368
369
if c != '>' {
369
370
if !c. is_whitespace ( ) {
@@ -416,6 +417,7 @@ impl TagParser {
416
417
' parse_til_gt: {
417
418
for ( i, c) in text[ pos..] . char_indices ( ) {
418
419
if !c. is_whitespace ( ) {
420
+ assert_eq ! ( self . quote_pos. is_some( ) , self . quote. is_some( ) ) ;
419
421
if let Some ( q) = self . quote {
420
422
if c == q {
421
423
self . quote = None ;
@@ -486,7 +488,7 @@ impl TagParser {
486
488
let mut prev_pos = 0 ;
487
489
loop {
488
490
if self . quote . is_some ( ) {
489
- assert ! ( self . in_attrs) ;
491
+ assert ! ( self . in_attrs && self . quote_pos . is_some ( ) ) ;
490
492
}
491
493
if self . in_attrs &&
492
494
let Some ( & ( start_pos, _) ) = iter. peek ( )
@@ -593,3 +595,24 @@ fn test_extract_tags_taglike_in_multievent_attr() {
593
595
p ( split_point..dox. len ( ) ) ;
594
596
assert_eq ! ( diags. borrow( ) . len( ) , 0 , "unexpected diagnostics: {diags:?}" ) ;
595
597
}
598
+
599
+ #[ test]
600
+ fn test_extract_tags_taglike_in_multiline_multievent_attr ( ) {
601
+ use std:: cell:: RefCell ;
602
+
603
+ let mut tagp = TagParser :: new ( ) ;
604
+ let diags = RefCell :: new ( Vec :: new ( ) ) ;
605
+ let dox = "<img src='\n foo:\n </div>\n <p/>\n <div>\n '>" ;
606
+ let mut p = |range : Range < usize > | {
607
+ tagp. extract_tags ( & dox[ range. clone ( ) ] , range, & mut None , & |s, r, b| {
608
+ diags. borrow_mut ( ) . push ( ( s, r. clone ( ) , b) ) ;
609
+ } ) } ;
610
+ let mut offset = 0 ;
611
+ for ln in dox. split_inclusive ( '\n' ) {
612
+ let new_offset = offset + ln. len ( ) ;
613
+ p ( offset..new_offset) ;
614
+ offset = new_offset;
615
+ }
616
+ assert_eq ! ( diags. borrow( ) . len( ) , 0 , "unexpected diagnostics: {diags:?}" ) ;
617
+ assert_eq ! ( tagp. tags. len( ) , 1 ) ;
618
+ }
0 commit comments