11//! HTML nodes.
22
3- #[ cfg( not( feature = "deterministic" ) ) ]
4- use ahash:: AHashMap as HashMap ;
5- #[ cfg( not( feature = "deterministic" ) ) ]
6- use std:: collections:: hash_map;
73use std:: fmt;
84use std:: ops:: Deref ;
95use std:: slice:: Iter as SliceIter ;
@@ -219,7 +215,7 @@ pub type Attributes = indexmap::IndexMap<QualName, StrTendril>;
219215/// Please enable the `deterministic` feature for order-preserving
220216/// (de)serialization.
221217#[ cfg( not( feature = "deterministic" ) ) ]
222- pub type Attributes = HashMap < QualName , StrTendril > ;
218+ pub type Attributes = Vec < ( QualName , StrTendril ) > ;
223219
224220/// An HTML element.
225221#[ derive( Clone , PartialEq , Eq ) ]
@@ -232,16 +228,20 @@ pub struct Element {
232228
233229 id : OnceCell < Option < StrTendril > > ,
234230
235- classes : OnceCell < Vec < LocalName > > ,
231+ classes : OnceCell < Box < [ LocalName ] > > ,
236232}
237233
238234impl Element {
239235 #[ doc( hidden) ]
240236 pub fn new ( name : QualName , attributes : Vec < Attribute > ) -> Self {
241- let attrs = attributes
237+ #[ allow( unused_mut) ]
238+ let mut attrs = attributes
242239 . 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 ) ) ;
245245
246246 Element {
247247 attrs,
@@ -277,17 +277,17 @@ impl Element {
277277 /// Returns an iterator over the element's classes.
278278 pub fn classes ( & self ) -> Classes {
279279 let classes = self . classes . get_or_init ( || {
280- let mut classes: Vec < LocalName > = self
280+ let mut classes = self
281281 . attrs
282282 . iter ( )
283283 . 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 < _ > > ( ) ;
286286
287287 classes. sort_unstable ( ) ;
288288 classes. dedup ( ) ;
289289
290- classes
290+ classes. into_boxed_slice ( )
291291 } ) ;
292292
293293 Classes {
@@ -298,7 +298,18 @@ impl Element {
298298 /// Returns the value of an attribute.
299299 pub fn attr ( & self , attr : & str ) -> Option < & str > {
300300 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
302313 }
303314
304315 /// Returns an iterator over the element's attributes.
@@ -330,7 +341,7 @@ pub type AttributesIter<'a> = indexmap::map::Iter<'a, QualName, StrTendril>;
330341
331342/// An iterator over a node's attributes.
332343#[ cfg( not( feature = "deterministic" ) ) ]
333- pub type AttributesIter < ' a > = hash_map :: Iter < ' a , QualName , StrTendril > ;
344+ pub type AttributesIter < ' a > = SliceIter < ' a , ( QualName , StrTendril ) > ;
334345
335346/// Iterator over attributes.
336347#[ allow( missing_debug_implementations) ]
0 commit comments