1
1
//! HTML nodes.
2
2
3
- #[ cfg( not( feature = "deterministic" ) ) ]
4
- use ahash:: AHashMap as HashMap ;
5
- #[ cfg( not( feature = "deterministic" ) ) ]
6
- use std:: collections:: hash_map;
7
3
use std:: fmt;
8
4
use std:: ops:: Deref ;
9
5
use std:: slice:: Iter as SliceIter ;
@@ -219,7 +215,7 @@ pub type Attributes = indexmap::IndexMap<QualName, StrTendril>;
219
215
/// Please enable the `deterministic` feature for order-preserving
220
216
/// (de)serialization.
221
217
#[ cfg( not( feature = "deterministic" ) ) ]
222
- pub type Attributes = HashMap < QualName , StrTendril > ;
218
+ pub type Attributes = Vec < ( QualName , StrTendril ) > ;
223
219
224
220
/// An HTML element.
225
221
#[ derive( Clone , PartialEq , Eq ) ]
@@ -232,16 +228,20 @@ pub struct Element {
232
228
233
229
id : OnceCell < Option < StrTendril > > ,
234
230
235
- classes : OnceCell < Vec < LocalName > > ,
231
+ classes : OnceCell < Box < [ LocalName ] > > ,
236
232
}
237
233
238
234
impl Element {
239
235
#[ doc( hidden) ]
240
236
pub fn new ( name : QualName , attributes : Vec < Attribute > ) -> Self {
241
- let attrs = attributes
237
+ #[ allow( unused_mut) ]
238
+ let mut attrs = attributes
242
239
. into_iter ( )
243
- . map ( |a| ( a. name , crate :: tendril_util:: make ( a. value ) ) )
244
- . collect ( ) ;
240
+ . map ( |attr| ( attr. name , crate :: tendril_util:: make ( attr. value ) ) )
241
+ . collect :: < Attributes > ( ) ;
242
+
243
+ #[ cfg( not( feature = "deterministic" ) ) ]
244
+ attrs. sort_unstable_by ( |lhs, rhs| lhs. 0 . cmp ( & rhs. 0 ) ) ;
245
245
246
246
Element {
247
247
attrs,
@@ -277,17 +277,17 @@ impl Element {
277
277
/// Returns an iterator over the element's classes.
278
278
pub fn classes ( & self ) -> Classes {
279
279
let classes = self . classes . get_or_init ( || {
280
- let mut classes: Vec < LocalName > = self
280
+ let mut classes = self
281
281
. attrs
282
282
. iter ( )
283
283
. filter ( |( name, _) | name. local . as_ref ( ) == "class" )
284
- . flat_map ( |( _, value) | value. split_whitespace ( ) . map ( LocalName :: from) )
285
- . collect ( ) ;
284
+ . flat_map ( |( _, value) | value. split_ascii_whitespace ( ) . map ( LocalName :: from) )
285
+ . collect :: < Vec < _ > > ( ) ;
286
286
287
287
classes. sort_unstable ( ) ;
288
288
classes. dedup ( ) ;
289
289
290
- classes
290
+ classes. into_boxed_slice ( )
291
291
} ) ;
292
292
293
293
Classes {
@@ -298,7 +298,18 @@ impl Element {
298
298
/// Returns the value of an attribute.
299
299
pub fn attr ( & self , attr : & str ) -> Option < & str > {
300
300
let qualname = QualName :: new ( None , ns ! ( ) , LocalName :: from ( attr) ) ;
301
- self . attrs . get ( & qualname) . map ( Deref :: deref)
301
+
302
+ #[ cfg( not( feature = "deterministic" ) ) ]
303
+ let value = self
304
+ . attrs
305
+ . binary_search_by ( |attr| attr. 0 . cmp ( & qualname) )
306
+ . ok ( )
307
+ . map ( |idx| & * self . attrs [ idx] . 1 ) ;
308
+
309
+ #[ cfg( feature = "deterministic" ) ]
310
+ let value = self . attrs . get ( & qualname) . map ( Deref :: deref) ;
311
+
312
+ value
302
313
}
303
314
304
315
/// Returns an iterator over the element's attributes.
@@ -330,7 +341,7 @@ pub type AttributesIter<'a> = indexmap::map::Iter<'a, QualName, StrTendril>;
330
341
331
342
/// An iterator over a node's attributes.
332
343
#[ cfg( not( feature = "deterministic" ) ) ]
333
- pub type AttributesIter < ' a > = hash_map :: Iter < ' a , QualName , StrTendril > ;
344
+ pub type AttributesIter < ' a > = SliceIter < ' a , ( QualName , StrTendril ) > ;
334
345
335
346
/// Iterator over attributes.
336
347
#[ allow( missing_debug_implementations) ]
0 commit comments