servo: Merge #13908 - Use enum BorderWidth as SpecifiedValue (from aethanyc:add-border-width-keyword); r=emilio
authorTing-Yu Lin <aethanyc@gmail.com>
Sat, 29 Oct 2016 19:48:27 -0500
changeset 340016 5e824991d68bc7a69b9213df90c2386af1aefb65
parent 340015 4e3e9401e49c29b16ac71b5df551252c2c2d49ec
child 340017 ca4eba73915fb8e59308317ff816536832bd073c
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
servo: Merge #13908 - Use enum BorderWidth as SpecifiedValue (from aethanyc:add-border-width-keyword); r=emilio Use enum BorderWidth instead of a tuple-like struct to store the specified value. BorderWidth is needed to be used in both longhand and shorthand border width properties, so I put it in `specified` module. Fixed #13869. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] These changes fix #13869 (github issue number if applicable). <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 357e746a9a37a68604fe5ae1c3fb30334f75b4ac
servo/components/script/dom/element.rs
servo/components/style/properties/longhand/border.mako.rs
servo/components/style/properties/shorthand/border.mako.rs
servo/components/style/values/specified/mod.rs
servo/tests/unit/style/properties/serialization.rs
servo/tests/unit/style/properties/viewport.rs
--- a/servo/components/script/dom/element.rs
+++ b/servo/components/script/dom/element.rs
@@ -83,17 +83,17 @@ use std::sync::Arc;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use string_cache::{Atom, Namespace, QualName};
 use style::attr::{AttrValue, LengthOrPercentageOrAuto};
 use style::element_state::*;
 use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes};
 use style::parser::ParserContextExtraData;
 use style::properties::{DeclaredValue, Importance};
 use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute};
-use style::properties::longhands::{self, background_image, border_spacing, font_family, font_size, overflow_x};
+use style::properties::longhands::{background_image, border_spacing, font_family, font_size, overflow_x};
 use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl};
 use style::selector_matching::ApplicableDeclarationBlock;
 use style::sink::Push;
 use style::values::CSSFloat;
 use style::values::specified::{self, CSSColor, CSSRGBA, LengthOrPercentage};
 
 // TODO: Update focus state when the top-level browsing context gains or loses system focus,
 // and when the element enters or leaves a browsing context container.
@@ -569,29 +569,26 @@ impl LayoutElementHelpers for LayoutJS<E
 
         let border = if let Some(this) = self.downcast::<HTMLTableElement>() {
             this.get_border()
         } else {
             None
         };
 
         if let Some(border) = border {
-            let width_value = specified::Length::Absolute(Au::from_px(border as i32));
+            let width_value = specified::BorderWidth::from_length(
+                specified::Length::Absolute(Au::from_px(border as i32)));
             hints.push(from_declaration(
-                PropertyDeclaration::BorderTopWidth(DeclaredValue::Value(
-                    longhands::border_top_width::SpecifiedValue(width_value)))));
+                PropertyDeclaration::BorderTopWidth(DeclaredValue::Value(width_value))));
             hints.push(from_declaration(
-                PropertyDeclaration::BorderLeftWidth(DeclaredValue::Value(
-                    longhands::border_left_width::SpecifiedValue(width_value)))));
+                PropertyDeclaration::BorderLeftWidth(DeclaredValue::Value(width_value))));
             hints.push(from_declaration(
-                PropertyDeclaration::BorderBottomWidth(DeclaredValue::Value(
-                    longhands::border_bottom_width::SpecifiedValue(width_value)))));
+                PropertyDeclaration::BorderBottomWidth(DeclaredValue::Value(width_value))));
             hints.push(from_declaration(
-                PropertyDeclaration::BorderRightWidth(DeclaredValue::Value(
-                    longhands::border_right_width::SpecifiedValue(width_value)))));
+                PropertyDeclaration::BorderRightWidth(DeclaredValue::Value(width_value))));
         }
     }
 
     #[allow(unsafe_code)]
     unsafe fn get_colspan(self) -> u32 {
         if let Some(this) = self.downcast::<HTMLTableCellElement>() {
             this.get_colspan().unwrap_or(1)
         } else {
--- a/servo/components/style/properties/longhand/border.mako.rs
+++ b/servo/components/style/properties/longhand/border.mako.rs
@@ -22,60 +22,33 @@
 % endfor
 
 % for side in ["top", "right", "bottom", "left"]:
     <%helpers:longhand name="border-${side}-width" animatable="True">
         use app_units::Au;
         use cssparser::ToCss;
         use std::fmt;
         use values::HasViewportPercentage;
+        use values::specified::BorderWidth;
 
-        impl ToCss for SpecifiedValue {
-            fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-                self.0.to_css(dest)
-            }
-        }
+        pub type SpecifiedValue = BorderWidth;
 
         #[inline]
         pub fn parse(_context: &ParserContext, input: &mut Parser)
-                               -> Result<SpecifiedValue, ()> {
-            specified::parse_border_width(input).map(SpecifiedValue)
-        }
-        #[derive(Debug, Clone, PartialEq)]
-        #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
-        pub struct SpecifiedValue(pub specified::Length);
-
-        impl HasViewportPercentage for SpecifiedValue {
-            fn has_viewport_percentage(&self) -> bool {
-                let &SpecifiedValue(length) = self;
-                length.has_viewport_percentage()
-            }
+                     -> Result<SpecifiedValue, ()> {
+            BorderWidth::parse(input)
         }
 
         pub mod computed_value {
             use app_units::Au;
             pub type T = Au;
         }
         #[inline] pub fn get_initial_value() -> computed_value::T {
             Au::from_px(3)  // medium
         }
-
-        impl ToComputedValue for SpecifiedValue {
-            type ComputedValue = computed_value::T;
-
-            #[inline]
-            fn to_computed_value(&self, context: &Context) -> computed_value::T {
-                self.0.to_computed_value(context)
-            }
-
-            #[inline]
-            fn from_computed_value(computed: &computed_value::T) -> Self {
-                SpecifiedValue(ToComputedValue::from_computed_value(computed))
-            }
-        }
     </%helpers:longhand>
 % endfor
 
 // FIXME(#4126): when gfx supports painting it, make this Size2D<LengthOrPercentage>
 % for corner in ["top-left", "top-right", "bottom-right", "bottom-left"]:
     ${helpers.predefined_type("border-" + corner + "-radius", "BorderRadiusSize",
                               "computed::BorderRadiusSize::zero()",
                               "parse",
--- a/servo/components/style/properties/shorthand/border.mako.rs
+++ b/servo/components/style/properties/shorthand/border.mako.rs
@@ -11,32 +11,29 @@
 <%helpers:shorthand name="border-width" sub_properties="${
         ' '.join('border-%s-width' % side
                  for side in ['top', 'right', 'bottom', 'left'])}">
     use super::parse_four_sides;
     use values::specified;
 
     pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
         let _unused = context;
-        let (top, right, bottom, left) = try!(parse_four_sides(input, specified::parse_border_width));
+        let (top, right, bottom, left) = try!(parse_four_sides(input, specified::BorderWidth::parse));
         Ok(Longhands {
             % for side in ["top", "right", "bottom", "left"]:
-                ${to_rust_ident('border-%s-width' % side)}:
-                    Some(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue(${side})),
+                ${to_rust_ident('border-%s-width' % side)}: Some(${side}),
             % endfor
         })
     }
 
     impl<'a> LonghandsToSerialize<'a>  {
         fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
-            // extract tuple container values so that the different border widths
-            // can be compared via partial eq
             % for side in ["top", "right", "bottom", "left"]:
                 let ${side} = match self.border_${side}_width {
-                    &DeclaredValue::Value(ref value) => DeclaredValue::Value(value.0),
+                    &DeclaredValue::Value(ref value) => DeclaredValue::Value(*value),
                     &DeclaredValue::WithVariables {
                         css: ref a, first_token_type: ref b, base_url: ref c, from_shorthand: ref d
                     } => DeclaredValue::WithVariables {
                         // WithVariables should not be reachable during serialization
                         css: a.clone(), first_token_type: b.clone(), base_url: c.clone(), from_shorthand: d.clone()
                     },
                     &DeclaredValue::Initial => DeclaredValue::Initial,
                     &DeclaredValue::Inherit => DeclaredValue::Inherit,
@@ -47,17 +44,17 @@
         }
     }
 </%helpers:shorthand>
 
 
 pub fn parse_border(context: &ParserContext, input: &mut Parser)
                  -> Result<(Option<specified::CSSColor>,
                             Option<specified::BorderStyle>,
-                            Option<specified::Length>), ()> {
+                            Option<specified::BorderWidth>), ()> {
     use values::specified;
     let _unused = context;
     let mut color = None;
     let mut style = None;
     let mut width = None;
     let mut any = false;
     loop {
         if color.is_none() {
@@ -70,17 +67,17 @@ pub fn parse_border(context: &ParserCont
         if style.is_none() {
             if let Ok(value) = input.try(specified::BorderStyle::parse) {
                 style = Some(value);
                 any = true;
                 continue
             }
         }
         if width.is_none() {
-            if let Ok(value) = input.try(specified::parse_border_width) {
+            if let Ok(value) = input.try(specified::BorderWidth::parse) {
                 width = Some(value);
                 any = true;
                 continue
             }
         }
         break
     }
     if any { Ok((color, style, width)) } else { Err(()) }
@@ -92,18 +89,17 @@ pub fn parse_border(context: &ParserCont
         for prop in ['color', 'style', 'width']
     )}">
 
     pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
         let (color, style, width) = try!(super::parse_border(context, input));
         Ok(Longhands {
             border_${side}_color: color,
             border_${side}_style: style,
-            border_${side}_width:
-                width.map(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue),
+            border_${side}_width: width
         })
     }
 
     impl<'a> LonghandsToSerialize<'a>  {
         fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             super::serialize_directional_border(
                 dest,
                 self.border_${side}_width,
@@ -123,18 +119,17 @@ pub fn parse_border(context: &ParserCont
 )}">
 
     pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
         let (color, style, width) = try!(super::parse_border(context, input));
         Ok(Longhands {
             % for side in ["top", "right", "bottom", "left"]:
                 border_${side}_color: color.clone(),
                 border_${side}_style: style,
-                border_${side}_width:
-                    width.map(longhands::${to_rust_ident('border-%s-width' % side)}::SpecifiedValue),
+                border_${side}_width: width,
             % endfor
         })
     }
 
     impl<'a> LonghandsToSerialize<'a>  {
         fn to_css_declared<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
             // If all longhands are all present, then all sides should be the same,
             // so we can just one set of color/style/width
--- a/servo/components/style/values/specified/mod.rs
+++ b/servo/components/style/values/specified/mod.rs
@@ -1299,16 +1299,85 @@ pub fn parse_border_width(input: &mut Pa
             "thin" => Ok(Length::from_px(1.)),
             "medium" => Ok(Length::from_px(3.)),
             "thick" => Ok(Length::from_px(5.)),
             _ => Err(())
         }
     })
 }
 
+#[derive(Clone, PartialEq, Copy, Debug)]
+#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
+pub enum BorderWidth {
+    Thin,
+    Medium,
+    Thick,
+    Width(Length),
+}
+
+impl BorderWidth {
+    pub fn from_length(length: Length) -> Self {
+        BorderWidth::Width(length)
+    }
+
+    pub fn parse(input: &mut Parser) -> Result<BorderWidth, ()> {
+        match input.try(Length::parse_non_negative) {
+            Ok(length) => Ok(BorderWidth::Width(length)),
+            Err(_) => match_ignore_ascii_case! { try!(input.expect_ident()),
+               "thin" => Ok(BorderWidth::Thin),
+               "medium" => Ok(BorderWidth::Medium),
+               "thick" => Ok(BorderWidth::Thick),
+               _ => Err(())
+            }
+        }
+    }
+}
+
+impl ToCss for BorderWidth {
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        match *self {
+            BorderWidth::Thin => dest.write_str("thin"),
+            BorderWidth::Medium => dest.write_str("medium"),
+            BorderWidth::Thick => dest.write_str("thick"),
+            BorderWidth::Width(length) => length.to_css(dest)
+        }
+    }
+}
+
+impl HasViewportPercentage for BorderWidth {
+    fn has_viewport_percentage(&self) -> bool {
+        match *self {
+            BorderWidth::Thin | BorderWidth::Medium | BorderWidth::Thick => false,
+            BorderWidth::Width(length) => length.has_viewport_percentage()
+         }
+    }
+}
+
+impl ToComputedValue for BorderWidth {
+    type ComputedValue = Au;
+
+    #[inline]
+    fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
+        // We choose the pixel length of the keyword values the same as both spec and gecko.
+        // Spec: https://drafts.csswg.org/css-backgrounds-3/#line-width
+        // Gecko: https://bugzilla.mozilla.org/show_bug.cgi?id=1312155#c0
+        match *self {
+            BorderWidth::Thin => Length::from_px(1.).to_computed_value(context),
+            BorderWidth::Medium => Length::from_px(3.).to_computed_value(context),
+            BorderWidth::Thick => Length::from_px(5.).to_computed_value(context),
+            BorderWidth::Width(length) => length.to_computed_value(context)
+        }
+    }
+
+    #[inline]
+    fn from_computed_value(computed: &Self::ComputedValue) -> Self {
+        BorderWidth::Width(ToComputedValue::from_computed_value(computed))
+    }
+}
+
 // The integer values here correspond to the border conflict resolution rules in CSS 2.1 ยง
 // 17.6.2.1. Higher values override lower values.
 define_numbered_css_keyword_enum! { BorderStyle:
     "none" => none = -1,
     "solid" => solid = 6,
     "double" => double = 7,
     "dotted" => dotted = 4,
     "dashed" => dashed = 5,
--- a/servo/tests/unit/style/properties/serialization.rs
+++ b/servo/tests/unit/style/properties/serialization.rs
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 pub use cssparser::ToCss;
 pub use std::sync::Arc;
 pub use style::computed_values::display::T::inline_block;
 pub use style::properties::{DeclaredValue, PropertyDeclaration, PropertyDeclarationBlock, Importance};
-pub use style::values::specified::{BorderStyle, CSSColor, Length};
+pub use style::values::specified::{BorderStyle, BorderWidth, CSSColor, Length};
 pub use style::values::specified::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrAutoOrContent};
 pub use style::properties::longhands::outline_color::computed_value::T as ComputedColor;
 pub use style::values::RGBA;
 pub use style::values::specified::UrlExtraData;
 pub use url::Url;
 
 #[test]
 fn property_declaration_block_should_serialize_correctly() {
@@ -187,39 +187,52 @@ mod shorthand_serialization {
             properties.push(PropertyDeclaration::PaddingLeft(px_15));
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "padding: 10px 15px;");
         }
 
         #[test]
         fn border_width_should_serialize_correctly() {
-            use style::properties::longhands::border_bottom_width::SpecifiedValue as BottomContainer;
-            use style::properties::longhands::border_left_width::SpecifiedValue as LeftContainer;
-            use style::properties::longhands::border_right_width::SpecifiedValue as RightContainer;
-            use style::properties::longhands::border_top_width::SpecifiedValue as TopContainer;
-
             let mut properties = Vec::new();
 
-            let top_px = DeclaredValue::Value(TopContainer(Length::from_px(10f32)));
-            let bottom_px = DeclaredValue::Value(BottomContainer(Length::from_px(10f32)));
+            let top_px = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(10f32)));
+            let bottom_px = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(10f32)));
 
-            let right_px = DeclaredValue::Value(RightContainer(Length::from_px(15f32)));
-            let left_px = DeclaredValue::Value(LeftContainer(Length::from_px(15f32)));
+            let right_px = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(15f32)));
+            let left_px = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(15f32)));
 
             properties.push(PropertyDeclaration::BorderTopWidth(top_px));
             properties.push(PropertyDeclaration::BorderRightWidth(right_px));
             properties.push(PropertyDeclaration::BorderBottomWidth(bottom_px));
             properties.push(PropertyDeclaration::BorderLeftWidth(left_px));
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-width: 10px 15px;");
         }
 
         #[test]
+        fn border_width_with_keywords_should_serialize_correctly() {
+            let mut properties = Vec::new();
+
+            let top_px = DeclaredValue::Value(BorderWidth::Thin);
+            let right_px = DeclaredValue::Value(BorderWidth::Medium);
+            let bottom_px = DeclaredValue::Value(BorderWidth::Thick);
+            let left_px = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(15f32)));
+
+            properties.push(PropertyDeclaration::BorderTopWidth(top_px));
+            properties.push(PropertyDeclaration::BorderRightWidth(right_px));
+            properties.push(PropertyDeclaration::BorderBottomWidth(bottom_px));
+            properties.push(PropertyDeclaration::BorderLeftWidth(left_px));
+
+            let serialization = shorthand_properties_to_string(properties);
+            assert_eq!(serialization, "border-width: thin medium thick 15px;");
+        }
+
+        #[test]
         fn border_color_should_serialize_correctly() {
             let mut properties = Vec::new();
 
             let red = DeclaredValue::Value(CSSColor {
                 parsed: ComputedColor::RGBA(RGBA { red: 1f32, green: 0f32, blue: 0f32, alpha: 1f32 }),
                 authored: None
             });
 
@@ -252,30 +265,26 @@ mod shorthand_serialization {
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-style: solid dotted;");
         }
     }
 
 
     mod border_shorthands {
-        use style::properties::longhands::border_bottom_width::SpecifiedValue as BottomContainer;
-        use style::properties::longhands::border_left_width::SpecifiedValue as LeftContainer;
-        use style::properties::longhands::border_right_width::SpecifiedValue as RightContainer;
-        use style::properties::longhands::border_top_width::SpecifiedValue as TopContainer;
         use super::*;
 
         // 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"
 
         #[test]
         fn directional_border_should_show_all_properties_when_values_are_set() {
             let mut properties = Vec::new();
 
-            let width = DeclaredValue::Value(TopContainer(Length::from_px(4f32)));
+            let width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let style = DeclaredValue::Value(BorderStyle::solid);
             let color = DeclaredValue::Value(CSSColor {
                 parsed: ComputedColor::RGBA(RGBA { red: 1f32, green: 0f32, blue: 0f32, alpha: 1f32 }),
                 authored: None
             });
 
             properties.push(PropertyDeclaration::BorderTopWidth(width));
             properties.push(PropertyDeclaration::BorderTopStyle(style));
@@ -284,17 +293,17 @@ mod shorthand_serialization {
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-top: 4px solid rgb(255, 0, 0);");
         }
 
         #[test]
         fn directional_border_with_no_specified_style_will_show_style_as_none() {
             let mut properties = Vec::new();
 
-            let width = DeclaredValue::Value(TopContainer(Length::from_px(4f32)));
+            let width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let style = DeclaredValue::Initial;
             let color = DeclaredValue::Value(CSSColor {
                 parsed: ComputedColor::RGBA(RGBA { red: 1f32, green: 0f32, blue: 0f32, alpha: 1f32 }),
                 authored: None
             });
 
             properties.push(PropertyDeclaration::BorderTopWidth(width));
             properties.push(PropertyDeclaration::BorderTopStyle(style));
@@ -303,105 +312,105 @@ mod shorthand_serialization {
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-top: 4px none rgb(255, 0, 0);");
         }
 
         #[test]
         fn directional_border_with_no_specified_color_will_not_show_color() {
             let mut properties = Vec::new();
 
-            let width = DeclaredValue::Value(TopContainer(Length::from_px(4f32)));
+            let width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let style = DeclaredValue::Value(BorderStyle::solid);
             let color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderTopWidth(width));
             properties.push(PropertyDeclaration::BorderTopStyle(style));
             properties.push(PropertyDeclaration::BorderTopColor(color));
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-top: 4px solid;");
         }
 
         #[test]
         fn border_right_should_serialize_correctly() {
             let mut properties = Vec::new();
 
-            let width = DeclaredValue::Value(RightContainer(Length::from_px(4f32)));
+            let width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let style = DeclaredValue::Value(BorderStyle::solid);
             let color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderRightWidth(width));
             properties.push(PropertyDeclaration::BorderRightStyle(style));
             properties.push(PropertyDeclaration::BorderRightColor(color));
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-right: 4px solid;");
         }
 
         #[test]
         fn border_bottom_should_serialize_correctly() {
             let mut properties = Vec::new();
 
-            let width = DeclaredValue::Value(BottomContainer(Length::from_px(4f32)));
+            let width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let style = DeclaredValue::Value(BorderStyle::solid);
             let color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderBottomWidth(width));
             properties.push(PropertyDeclaration::BorderBottomStyle(style));
             properties.push(PropertyDeclaration::BorderBottomColor(color));
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-bottom: 4px solid;");
         }
 
         #[test]
         fn border_left_should_serialize_correctly() {
             let mut properties = Vec::new();
 
-            let width = DeclaredValue::Value(LeftContainer(Length::from_px(4f32)));
+            let width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let style = DeclaredValue::Value(BorderStyle::solid);
             let color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderLeftWidth(width));
             properties.push(PropertyDeclaration::BorderLeftStyle(style));
             properties.push(PropertyDeclaration::BorderLeftColor(color));
 
             let serialization = shorthand_properties_to_string(properties);
             assert_eq!(serialization, "border-left: 4px solid;");
         }
 
         #[test]
         fn border_should_serialize_correctly() {
             let mut properties = Vec::new();
 
-            let top_width = DeclaredValue::Value(TopContainer(Length::from_px(4f32)));
+            let top_width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let top_style = DeclaredValue::Value(BorderStyle::solid);
             let top_color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderTopWidth(top_width));
             properties.push(PropertyDeclaration::BorderTopStyle(top_style));
             properties.push(PropertyDeclaration::BorderTopColor(top_color));
 
-            let right_width = DeclaredValue::Value(RightContainer(Length::from_px(4f32)));
+            let right_width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let right_style = DeclaredValue::Value(BorderStyle::solid);
             let right_color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderRightWidth(right_width));
             properties.push(PropertyDeclaration::BorderRightStyle(right_style));
             properties.push(PropertyDeclaration::BorderRightColor(right_color));
 
-            let bottom_width = DeclaredValue::Value(BottomContainer(Length::from_px(4f32)));
+            let bottom_width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let bottom_style = DeclaredValue::Value(BorderStyle::solid);
             let bottom_color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderBottomWidth(bottom_width));
             properties.push(PropertyDeclaration::BorderBottomStyle(bottom_style));
             properties.push(PropertyDeclaration::BorderBottomColor(bottom_color));
 
-            let left_width = DeclaredValue::Value(LeftContainer(Length::from_px(4f32)));
+            let left_width = DeclaredValue::Value(BorderWidth::from_length(Length::from_px(4f32)));
             let left_style = DeclaredValue::Value(BorderStyle::solid);
             let left_color = DeclaredValue::Initial;
 
             properties.push(PropertyDeclaration::BorderLeftWidth(left_width));
             properties.push(PropertyDeclaration::BorderLeftStyle(left_style));
             properties.push(PropertyDeclaration::BorderLeftColor(left_color));
 
             let serialization = shorthand_properties_to_string(properties);
--- a/servo/tests/unit/style/properties/viewport.rs
+++ b/servo/tests/unit/style/properties/viewport.rs
@@ -7,21 +7,21 @@ use style::properties::{DeclaredValue, P
 use style::properties::longhands::border_top_width;
 use style::values::HasViewportPercentage;
 use style::values::specified::{Length, ViewportPercentageLength};
 
 #[test]
 fn has_viewport_percentage_for_specified_value() {
     //TODO: test all specified value with a HasViewportPercentage impl
     let pvw = PropertyDeclaration::BorderTopWidth(
-        DeclaredValue::Value(border_top_width::SpecifiedValue(
+        DeclaredValue::Value(border_top_width::SpecifiedValue::from_length(
             Length::ViewportPercentage(ViewportPercentageLength::Vw(100.))
         ))
     );
     assert!(pvw.has_viewport_percentage());
 
     let pabs = PropertyDeclaration::BorderTopWidth(
-        DeclaredValue::Value(border_top_width::SpecifiedValue(
+        DeclaredValue::Value(border_top_width::SpecifiedValue::from_length(
             Length::Absolute(Au(100))
         ))
     );
     assert!(!pabs.has_viewport_percentage());
 }