diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index c332b4b07da..efbccd9f991 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -14,6 +14,7 @@ use parser::{ParserContext, log_css_error}; use properties::animated_properties::AnimationValue; use selectors::parser::SelectorParseError; use shared_lock::Locked; +use smallvec::SmallVec; use std::fmt; use std::slice::Iter; use style_traits::{PARSING_MODE_DEFAULT, ToCss, ParseError, ParsingMode, StyleParseError}; @@ -605,24 +606,31 @@ impl ToCss for PropertyDeclarationBlock { // Step 3.3 let shorthands = declaration.shorthands(); if !shorthands.is_empty() { - // Step 3.3.1 - // - // FIXME(emilio): All this looks terribly inefficient... - let mut longhands = self.declarations.iter() - .filter(|d| !already_serialized.contains(d.0.id())) - .collect::>(); + // Step 3.3.1 is done by checking already_serialized while + // iterating below. // Step 3.3.2 for &shorthand in shorthands { let properties = shorthand.longhands(); // Substep 2 & 3 - let mut current_longhands = Vec::new(); + let mut current_longhands = SmallVec::<[_; 10]>::new(); let mut important_count = 0; let mut found_system = None; - if shorthand == ShorthandId::Font && longhands.iter().any(|&&(ref l, _)| l.get_system().is_some()) { - for &&(ref longhand, longhand_importance) in longhands.iter() { + let is_system_font = + shorthand == ShorthandId::Font && + self.declarations.iter().any(|&(ref l, _)| { + !already_serialized.contains(l.id()) && + l.get_system().is_some() + }); + + if is_system_font { + for &(ref longhand, longhand_importance) in &self.declarations { + if already_serialized.contains(longhand.id()) { + continue; + } + if longhand.get_system().is_some() || longhand.is_default_line_height() { current_longhands.push(longhand); if found_system.is_none() { @@ -634,7 +642,11 @@ impl ToCss for PropertyDeclarationBlock { } } } else { - for &&(ref longhand, longhand_importance) in longhands.iter() { + for &(ref longhand, longhand_importance) in &self.declarations { + if already_serialized.contains(longhand.id()) { + continue; + } + if longhand.id().is_longhand_of(shorthand) { current_longhands.push(longhand); if longhand_importance.important() { @@ -728,11 +740,6 @@ impl ToCss for PropertyDeclarationBlock { for current_longhand in ¤t_longhands { // Substep 9 already_serialized.insert(current_longhand.id()); - let index_to_remove = longhands.iter().position(|l| l.0 == **current_longhand); - if let Some(index) = index_to_remove { - // Substep 10 - longhands.remove(index); - } } } }