@@ -19,7 +19,7 @@ static TEXT_END: &[u8] = &[ b'<' , b'\n'];
19
19
20
20
/// Characters that indicate the end of
21
21
/// an attribute name
22
- static ATTRIBUTE_NAME_END : & [ u8 ] = & [ b'=' , b'>' , b' ' , b'\t' ] ;
22
+ static ATTRIBUTE_NAME_END : & [ u8 ] = & [ b'=' , b'>' , b' ' , b'\t' , b'\n' ] ;
23
23
24
24
static ATTRIBUTE_VALUE_END : & [ u8 ] = & [ b' ' , b'\t' , b'>' , b'/' ] ;
25
25
@@ -493,10 +493,12 @@ impl<'a> SAXParser<'a> {
493
493
let mut byte = current[ 0 ] ;
494
494
495
495
if !TAG_NAME_END . contains ( & byte) {
496
- if let Some ( ( span, _ ) ) = gc. take_until_one_found ( TAG_NAME_END , true ) {
496
+ if let Some ( ( span, found ) ) = gc. take_until_one_found ( TAG_NAME_END , true ) {
497
497
byte = span[ span. len ( ) - 1 ] ;
498
+ self . tag . header . 1 = if found { gc. last_cursor_pos } else { gc. cursor } ;
499
+ } else {
500
+ self . tag . header . 1 = gc. last_cursor_pos ;
498
501
}
499
- self . tag . header . 1 = gc. last_cursor_pos ;
500
502
}
501
503
502
504
if self . events [ Event :: OpenTagStart ] {
@@ -870,6 +872,7 @@ impl<'a> SAXParser<'a> {
870
872
self . attribute . name . start = [ gc. line , gc. character . saturating_sub ( 1 ) ] ;
871
873
self . attribute . name . header . 0 = gc. last_cursor_pos ;
872
874
self . state = State :: AttribName ;
875
+ self . attribute_name ( gc, current) ;
873
876
}
874
877
}
875
878
}
@@ -878,6 +881,7 @@ impl<'a> SAXParser<'a> {
878
881
match current[ 0 ] {
879
882
b'=' => {
880
883
self . attribute . name . end = [ gc. line , gc. character . saturating_sub ( 1 ) ] ;
884
+ self . attribute . name . header . 1 = gc. cursor . saturating_sub ( 1 ) ;
881
885
self . state = State :: AttribValue ;
882
886
}
883
887
b'>' => {
@@ -938,8 +942,8 @@ impl<'a> SAXParser<'a> {
938
942
self . attribute . attr_type = AttrType :: JSX ;
939
943
self . brace_ct += 1 ;
940
944
} else {
945
+ self . attribute . value . header . 0 = gc. last_cursor_pos ;
941
946
self . state = State :: AttribValueUnquoted ;
942
- gc. take_until_one_found ( ATTRIBUTE_VALUE_END , false ) ;
943
947
}
944
948
}
945
949
@@ -966,22 +970,30 @@ impl<'a> SAXParser<'a> {
966
970
} else {
967
971
self . attribute . name . header . 0 = gc. last_cursor_pos ;
968
972
self . state = State :: AttribName ;
973
+ self . attribute_name ( gc, current) ;
969
974
}
970
975
}
971
976
972
977
#[ cold]
973
978
fn attribute_value_unquoted ( & mut self , gc : & mut GraphemeClusters , current : & [ u8 ] ) {
974
- let byte = current[ 0 ] ;
975
- if byte != b'>' || byte < 33 {
979
+ let mut byte = current[ 0 ] ;
980
+ if byte < 33 {
976
981
return ;
977
982
}
983
+ if let Some ( ( span, found) ) = gc. take_until_one_found ( ATTRIBUTE_VALUE_END , true ) {
984
+ byte = span[ span. len ( ) - 1 ] ;
985
+ self . attribute . value . header . 1 = if found { gc. last_cursor_pos } else { gc. cursor } ;
986
+ } else {
987
+ self . attribute . value . header . 1 = gc. last_cursor_pos ;
988
+ }
978
989
self . attribute . value . end = [ gc. line , gc. character . saturating_sub ( 1 ) ] ;
979
- self . attribute . value . header . 1 = gc . last_cursor_pos ;
990
+
980
991
self . process_attribute ( ) ;
981
992
if byte == b'>' {
982
993
self . process_open_tag ( false , gc) ;
983
994
} else {
984
995
self . state = State :: Attrib ;
996
+ self . attribute ( gc, & [ byte] ) ;
985
997
}
986
998
}
987
999
@@ -1248,6 +1260,85 @@ mod tests {
1248
1260
Ok ( ( ) )
1249
1261
}
1250
1262
#[ test]
1263
+ fn test_attribute_single_character_boolean ( ) -> Result < ( ) > {
1264
+ let event_handler = TextEventHandler :: new ( ) ;
1265
+ let mut sax = SAXParser :: new ( & event_handler) ;
1266
+ let mut events = [ false ; 10 ] ;
1267
+ events[ Event :: Attribute ] = true ;
1268
+ events[ Event :: CloseTag ] = true ;
1269
+ events[ Event :: Text ] = true ;
1270
+ sax. events = events;
1271
+ let str = r#"<element attribute1='value1'a attribute3='value3'></element>"# ;
1272
+
1273
+ sax. write ( str. as_bytes ( ) ) ;
1274
+ sax. identity ( ) ;
1275
+
1276
+ let attrs = event_handler. attributes . borrow ( ) ;
1277
+ let texts = event_handler. texts . borrow ( ) ;
1278
+ assert_eq ! ( attrs. len( ) , 3 ) ;
1279
+ assert_eq ! ( attrs[ 0 ] . name. value, b"attribute1" ) ;
1280
+ assert_eq ! ( attrs[ 0 ] . value. value, b"value1" ) ;
1281
+ assert_eq ! ( attrs[ 1 ] . name. value, b"a" ) ;
1282
+ assert_eq ! ( attrs[ 1 ] . value. value, b"" ) ;
1283
+ assert_eq ! ( attrs[ 2 ] . name. value, b"attribute3" ) ;
1284
+ assert_eq ! ( attrs[ 2 ] . value. value, b"value3" ) ;
1285
+ assert_eq ! ( texts. len( ) , 0 ) ;
1286
+
1287
+ Ok ( ( ) )
1288
+ }
1289
+ #[ test]
1290
+ fn test_attribute_unquoted ( ) -> Result < ( ) > {
1291
+ let event_handler = TextEventHandler :: new ( ) ;
1292
+ let mut sax = SAXParser :: new ( & event_handler) ;
1293
+ let mut events = [ false ; 10 ] ;
1294
+ events[ Event :: Attribute ] = true ;
1295
+ events[ Event :: CloseTag ] = true ;
1296
+ events[ Event :: Text ] = true ;
1297
+ sax. events = events;
1298
+ let str = r#"<element attribute1=value1 attribute2='value2'></element>"# ;
1299
+
1300
+ sax. write ( str. as_bytes ( ) ) ;
1301
+ sax. identity ( ) ;
1302
+
1303
+ let attrs = event_handler. attributes . borrow ( ) ;
1304
+ let texts = event_handler. texts . borrow ( ) ;
1305
+ assert_eq ! ( attrs. len( ) , 2 ) ;
1306
+ assert_eq ! ( attrs[ 0 ] . name. value, b"attribute1" ) ;
1307
+ assert_eq ! ( attrs[ 0 ] . value. value, b"value1" ) ;
1308
+ assert_eq ! ( attrs[ 1 ] . name. value, b"attribute2" ) ;
1309
+ assert_eq ! ( attrs[ 1 ] . value. value, b"value2" ) ;
1310
+ assert_eq ! ( texts. len( ) , 0 ) ;
1311
+
1312
+ Ok ( ( ) )
1313
+ }
1314
+ #[ test]
1315
+ fn test_attribute_single_character ( ) -> Result < ( ) > {
1316
+ let event_handler = TextEventHandler :: new ( ) ;
1317
+ let mut sax = SAXParser :: new ( & event_handler) ;
1318
+ let mut events = [ false ; 10 ] ;
1319
+ events[ Event :: Attribute ] = true ;
1320
+ events[ Event :: CloseTag ] = true ;
1321
+ events[ Event :: Text ] = true ;
1322
+ sax. events = events;
1323
+ let str = r#"<element attribute1='value1'a="value2" attribute3='value3'></element>"# ;
1324
+
1325
+ sax. write ( str. as_bytes ( ) ) ;
1326
+ sax. identity ( ) ;
1327
+
1328
+ let attrs = event_handler. attributes . borrow ( ) ;
1329
+ let texts = event_handler. texts . borrow ( ) ;
1330
+ assert_eq ! ( attrs. len( ) , 3 ) ;
1331
+ assert_eq ! ( attrs[ 0 ] . name. value, b"attribute1" ) ;
1332
+ assert_eq ! ( attrs[ 0 ] . value. value, b"value1" ) ;
1333
+ assert_eq ! ( attrs[ 1 ] . name. value, b"a" ) ;
1334
+ assert_eq ! ( attrs[ 1 ] . value. value, b"value2" ) ;
1335
+ assert_eq ! ( attrs[ 2 ] . name. value, b"attribute3" ) ;
1336
+ assert_eq ! ( attrs[ 2 ] . value. value, b"value3" ) ;
1337
+ assert_eq ! ( texts. len( ) , 0 ) ;
1338
+
1339
+ Ok ( ( ) )
1340
+ }
1341
+ #[ test]
1251
1342
fn test_empty_tag ( ) -> Result < ( ) > {
1252
1343
let event_handler = TextEventHandler :: new ( ) ;
1253
1344
let mut sax = SAXParser :: new ( & event_handler) ;
0 commit comments