diff --git a/components/style/properties/declaration_block.rs b/components/style/properties/declaration_block.rs index c458bad1717..a87b87fe9db 100644 --- a/components/style/properties/declaration_block.rs +++ b/components/style/properties/declaration_block.rs @@ -657,10 +657,6 @@ impl ToCss for PropertyDeclarationBlock { if is_system_font { for (longhand, importance) in self.declaration_importance_iter() { - 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() { @@ -673,10 +669,6 @@ impl ToCss for PropertyDeclarationBlock { } } else { for (longhand, importance) in self.declaration_importance_iter() { - if already_serialized.contains(longhand.id()) { - continue; - } - if longhand.id().is_longhand_of(shorthand) { current_longhands.push(longhand); if importance.important() { @@ -771,6 +763,13 @@ impl ToCss for PropertyDeclarationBlock { // Substep 9 already_serialized.insert(current_longhand.id()); } + + // FIXME(https://github.com/w3c/csswg-drafts/issues/1774) + // The specification does not include an instruction to abort + // the shorthand loop at this point, but doing so both matches + // Gecko and makes sense since shorthands are checked in + // preferred order. + break; } } diff --git a/tests/unit/style/properties/serialization.rs b/tests/unit/style/properties/serialization.rs index 751db0eab32..3216293ab75 100644 --- a/tests/unit/style/properties/serialization.rs +++ b/tests/unit/style/properties/serialization.rs @@ -341,6 +341,53 @@ mod shorthand_serialization { mod border_shorthands { use super::*; + #[test] + fn border_top_and_color() { + let mut properties = Vec::new(); + properties.push(PropertyDeclaration::BorderTopWidth(BorderSideWidth::Length(Length::from_px(1.)))); + properties.push(PropertyDeclaration::BorderTopStyle(BorderStyle::solid)); + let c = Color::Numeric { + parsed: RGBA::new(255, 0, 0, 255), + authored: Some("green".to_string().into_boxed_str()) + }; + properties.push(PropertyDeclaration::BorderTopColor(c)); + let c = Color::Numeric { + parsed: RGBA::new(0, 255, 0, 255), + authored: Some("red".to_string().into_boxed_str()) + }; + properties.push(PropertyDeclaration::BorderTopColor(c.clone())); + properties.push(PropertyDeclaration::BorderBottomColor(c.clone())); + properties.push(PropertyDeclaration::BorderLeftColor(c.clone())); + properties.push(PropertyDeclaration::BorderRightColor(c.clone())); + + let serialization = shorthand_properties_to_string(properties); + assert_eq!(serialization, "border-top: 1px solid red; border-color: red;"); + } + + #[test] + fn border_color_and_top() { + let mut properties = Vec::new(); + let c = Color::Numeric { + parsed: RGBA::new(0, 255, 0, 255), + authored: Some("red".to_string().into_boxed_str()) + }; + properties.push(PropertyDeclaration::BorderTopColor(c.clone())); + properties.push(PropertyDeclaration::BorderBottomColor(c.clone())); + properties.push(PropertyDeclaration::BorderLeftColor(c.clone())); + properties.push(PropertyDeclaration::BorderRightColor(c.clone())); + + properties.push(PropertyDeclaration::BorderTopWidth(BorderSideWidth::Length(Length::from_px(1.)))); + properties.push(PropertyDeclaration::BorderTopStyle(BorderStyle::solid)); + let c = Color::Numeric { + parsed: RGBA::new(255, 0, 0, 255), + authored: Some("green".to_string().into_boxed_str()) + }; + properties.push(PropertyDeclaration::BorderTopColor(c)); + + let serialization = shorthand_properties_to_string(properties); + assert_eq!(serialization, "border-color: green red red; border-top: 1px solid green;"); + } + // we can use border-top as a base to test out the different combinations // but afterwards, we only need to to one test per "directional border shorthand"