servo: Merge #10407 - Move some CSS properties to match Gecko's representation (from mauricioc:issue10403); r=bholley
authorMauricio Collares <mau@ric.io>
Thu, 07 Apr 2016 02:48:45 +0500
changeset 338433 2f088df3c986ef9a37909ff948e740e3d62fe754
parent 338432 d4740df2a5b7e3ae1afba1b59ef4e964d5b34da8
child 338434 e0982ea8e93e42207bd4713d299a27f7dc70caaa
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)
reviewersbholley
servo: Merge #10407 - Move some CSS properties to match Gecko's representation (from mauricioc:issue10403); r=bholley Fixes #10403. Animation had an extra transition-delay property, which was also moved to Box. Let me know if I should squash the commits. Source-Repo: https://github.com/servo/servo Source-Revision: 256b865055c10082731b218f41373d47ad632062
servo/components/layout/block.rs
servo/components/layout/display_list_builder.rs
servo/components/layout/flex.rs
servo/components/layout/fragment.rs
servo/components/layout/incremental.rs
servo/components/layout/inline.rs
servo/components/layout/text.rs
servo/components/layout/wrapper.rs
servo/components/style/animation.rs
servo/components/style/properties.mako.rs
--- a/servo/components/layout/block.rs
+++ b/servo/components/layout/block.rs
@@ -354,17 +354,17 @@ impl CandidateBSizeIterator {
                 calc.length() + block_container_block_size.scale_by(calc.percentage())
             }
             (LengthOrPercentage::Calc(calc), None) => calc.length(),
             (LengthOrPercentage::Percentage(_), None) => Au(0),
             (LengthOrPercentage::Length(length), _) => length,
         };
 
         // If the style includes `box-sizing: border-box`, subtract the border and padding.
-        let adjustment_for_box_sizing = match fragment.style.get_box().box_sizing {
+        let adjustment_for_box_sizing = match fragment.style.get_position().box_sizing {
             box_sizing::T::border_box => fragment.border_padding.block_start_end(),
             box_sizing::T::content_box => Au(0),
         };
 
         return CandidateBSizeIterator {
             block_size: block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
             max_block_size: max_block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
             min_block_size: adjust(min_block_size, adjustment_for_box_sizing),
@@ -1303,17 +1303,17 @@ impl BlockFlow {
                                                                         WritingMode,
                                                                         &mut Au,
                                                                         &mut Au) {
         let flags = self.base.flags.clone();
 
         let opaque_self = OpaqueFlow::from_flow(self);
 
         // Calculate non-auto block size to pass to children.
-        let box_border = match self.fragment.style().get_box().box_sizing {
+        let box_border = match self.fragment.style().get_position().box_sizing {
             box_sizing::T::border_box => self.fragment.border_padding.block_start_end(),
             box_sizing::T::content_box => Au(0),
         };
         let parent_container_size = self.explicit_block_containing_size(layout_context);
         // https://drafts.csswg.org/css-ui-3/#box-sizing
         let explicit_content_size = self
                                     .explicit_block_size(parent_container_size)
                                     .map(|x| if x < box_border { Au(0) } else { x - box_border });
@@ -2184,17 +2184,17 @@ pub trait ISizeAndMarginsComputer {
         block.fragment.compute_block_direction_margins(containing_block_inline_size);
         block.fragment.compute_inline_direction_margins(containing_block_inline_size);
         self.compute_border_and_padding(block, containing_block_inline_size);
 
         let mut computed_inline_size = self.initial_computed_inline_size(block,
                                                                          parent_flow_inline_size,
                                                                          layout_context);
         let style = block.fragment.style();
-        match (computed_inline_size, style.get_box().box_sizing) {
+        match (computed_inline_size, style.get_position().box_sizing) {
             (MaybeAuto::Specified(size), box_sizing::T::border_box) => {
                 computed_inline_size =
                     MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end())
             }
             (MaybeAuto::Auto, box_sizing::T::border_box) |
             (_, box_sizing::T::content_box) => {}
         }
 
--- a/servo/components/layout/display_list_builder.rs
+++ b/servo/components/layout/display_list_builder.rs
@@ -1117,17 +1117,17 @@ impl FragmentDisplayListBuilding for Fra
 
                 // TODO(emilio): Allow changing more properties by ::selection
                 let text_color = if text_fragment.selected() {
                     self.selected_style().get_color().color
                 } else {
                     self.style().get_color().color
                 };
 
-                for text_shadow in self.style.get_effects().text_shadow.0.iter().rev() {
+                for text_shadow in self.style.get_inheritedtext().text_shadow.0.iter().rev() {
                     let offset = &Point2D::new(text_shadow.offset_x, text_shadow.offset_y);
                     let color = self.style().resolve_color(text_shadow.color);
                     self.build_display_list_for_text_fragment(state,
                                                               &**text_fragment,
                                                               color,
                                                               &stacking_relative_content_box,
                                                               Some(text_shadow.blur_radius),
                                                               offset,
--- a/servo/components/layout/flex.rs
+++ b/servo/components/layout/flex.rs
@@ -20,17 +20,16 @@ use fragment::{Fragment, FragmentBorderB
 use gfx::display_list::{StackingContext, StackingContextId};
 use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
 use layout_debug;
 use model::{IntrinsicISizes, MaybeAuto, MinMaxConstraint};
 use std::cmp::max;
 use std::sync::Arc;
 use style::computed_values::flex_direction;
 use style::logical_geometry::LogicalSize;
-use style::properties::style_structs;
 use style::properties::{ComputedValues, ServoComputedValues};
 use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
 
 /// The size of an axis. May be a specified size, a min/max
 /// constraint, or an unlimited size
 #[derive(Debug)]
 enum AxisSize {
     Definite(Au),
@@ -83,20 +82,16 @@ pub struct FlexFlow {
     /// The cross axis will be parallel with the opposite logical axis.
     main_mode: Mode,
     /// The available main axis size
     available_main_size: AxisSize,
     /// The available cross axis size
     available_cross_size: AxisSize
 }
 
-fn flex_style(fragment: &Fragment) -> &style_structs::Flex {
-    fragment.style.get_flex()
-}
-
 // TODO(zentner): This function should use flex-basis.
 fn flex_item_inline_sizes(flow: &mut Flow) -> IntrinsicISizes {
     let _scope = layout_debug_scope!("flex::flex_item_inline_sizes");
     debug!("flex_item_inline_sizes");
     let base = flow::mut_base(flow);
 
     debug!("FlexItem intrinsic inline sizes: {:?}, {:?}",
            base.intrinsic_inline_sizes.minimum_inline_size,
@@ -108,17 +103,17 @@ fn flex_item_inline_sizes(flow: &mut Flo
     }
 }
 
 impl FlexFlow {
     pub fn from_fragment(fragment: Fragment,
                          flotation: Option<FloatKind>)
                          -> FlexFlow {
 
-        let main_mode = match flex_style(&fragment).flex_direction {
+        let main_mode = match fragment.style.get_position().flex_direction {
             flex_direction::T::row_reverse | flex_direction::T::row => Mode::Inline,
             flex_direction::T::column_reverse | flex_direction::T::column => Mode::Block
         };
 
         FlexFlow {
             block_flow: BlockFlow::from_fragment(fragment, flotation),
             main_mode: main_mode,
             available_main_size: AxisSize::Infinite,
--- a/servo/components/layout/fragment.rs
+++ b/servo/components/layout/fragment.rs
@@ -2187,17 +2187,17 @@ impl Fragment {
                 return true
             }
             transform_style::T::auto => {}
         }
 
         // FIXME(pcwalton): Don't unconditionally form stacking contexts for `overflow_x: scroll`
         // and `overflow_y: scroll`. This needs multiple layers per stacking context.
         match (self.style().get_box().position,
-               self.style().get_box().z_index,
+               self.style().get_position().z_index,
                self.style().get_box().overflow_x,
                self.style().get_box().overflow_y.0) {
             (position::T::absolute,
              z_index::T::Auto,
              overflow_x::T::visible,
              overflow_x::T::visible) |
             (position::T::fixed,
              z_index::T::Auto,
@@ -2219,25 +2219,25 @@ impl Fragment {
     }
 
     // Get the effective z-index of this fragment. Z-indices only apply to positioned element
     // per CSS 2 9.9.1 (http://www.w3.org/TR/CSS2/visuren.html#z-index), so this value may differ
     // from the value specified in the style.
     pub fn effective_z_index(&self) -> i32 {
         match self.style().get_box().position {
             position::T::static_ => {},
-            _ => return self.style().get_box().z_index.number_or_zero(),
+            _ => return self.style().get_position().z_index.number_or_zero(),
         }
 
         if self.style().get_effects().transform.0.is_some() {
-            return self.style().get_box().z_index.number_or_zero();
+            return self.style().get_position().z_index.number_or_zero();
         }
 
         match self.style().get_box().display {
-            display::T::flex => self.style().get_box().z_index.number_or_zero(),
+            display::T::flex => self.style().get_position().z_index.number_or_zero(),
             _ => 0,
         }
     }
 
     /// Computes the overflow rect of this fragment relative to the start of the flow.
     pub fn compute_overflow(&self,
                             flow_size: &Size2D<Au>,
                             relative_containing_block_size: &LogicalSize<Au>)
--- a/servo/components/layout/incremental.rs
+++ b/servo/components/layout/incremental.rs
@@ -171,70 +171,70 @@ pub fn compute_damage(old: Option<&Arc<S
                       [
                           REPAINT,
                           STORE_OVERFLOW,
                           BUBBLE_ISIZES,
                           REFLOW_OUT_OF_FLOW,
                           REFLOW,
                           RECONSTRUCT_FLOW
                       ], [
-        get_box.float, get_box.display, get_box.position, get_box.content,
+        get_box.float, get_box.display, get_box.position, get_counters.content,
         get_counters.counter_reset, get_counters.counter_increment,
         get_list.quotes, get_list.list_style_type,
 
         // If these text or font properties change, we need to reconstruct the flow so that
         // text shaping is re-run.
         get_inheritedtext.letter_spacing, get_inheritedtext.text_rendering,
         get_inheritedtext.text_transform, get_inheritedtext.word_spacing,
         get_inheritedtext.overflow_wrap, get_inheritedtext.text_justify,
-        get_inheritedtext.white_space, get_inheritedtext.word_break, get_inheritedtext.text_overflow,
+        get_inheritedtext.white_space, get_inheritedtext.word_break, get_text.text_overflow,
         get_font.font_family, get_font.font_style, get_font.font_variant, get_font.font_weight,
         get_font.font_size, get_font.font_stretch,
         get_inheritedbox.direction, get_inheritedbox.writing_mode,
         get_inheritedbox.text_orientation,
         get_text.text_decoration, get_text.unicode_bidi,
         get_inheritedtable.empty_cells, get_inheritedtable.caption_side,
         get_column.column_width, get_column.column_count
     ]) || add_if_not_equal!(old, new, damage,
                             [ REPAINT, STORE_OVERFLOW, BUBBLE_ISIZES, REFLOW_OUT_OF_FLOW, REFLOW ],
         [get_border.border_top_width, get_border.border_right_width,
         get_border.border_bottom_width, get_border.border_left_width,
         get_margin.margin_top, get_margin.margin_right,
         get_margin.margin_bottom, get_margin.margin_left,
         get_padding.padding_top, get_padding.padding_right,
         get_padding.padding_bottom, get_padding.padding_left,
         get_box.width, get_box.height,
-        get_inheritedbox.line_height,
+        get_inheritedtext.line_height,
         get_inheritedtext.text_align, get_inheritedtext.text_indent,
         get_table.table_layout,
         get_inheritedtable.border_collapse,
         get_inheritedtable.border_spacing,
         get_column.column_gap,
-        get_flex.flex_direction
+        get_position.flex_direction
     ]) || add_if_not_equal!(old, new, damage,
                             [ REPAINT, STORE_OVERFLOW, REFLOW_OUT_OF_FLOW ], [
-        get_positionoffsets.top, get_positionoffsets.left,
-        get_positionoffsets.right, get_positionoffsets.bottom
+        get_position.top, get_position.left,
+        get_position.right, get_position.bottom
     ]) || add_if_not_equal!(old, new, damage,
                             [ REPAINT ], [
         get_color.color, get_background.background_color,
         get_background.background_image, get_background.background_position,
         get_background.background_repeat, get_background.background_attachment,
         get_background.background_clip, get_background.background_origin,
         get_background.background_size,
         get_border.border_top_color, get_border.border_right_color,
         get_border.border_bottom_color, get_border.border_left_color,
         get_border.border_top_style, get_border.border_right_style,
         get_border.border_bottom_style, get_border.border_left_style,
         get_border.border_top_left_radius, get_border.border_top_right_radius,
         get_border.border_bottom_left_radius, get_border.border_bottom_right_radius,
-        get_box.z_index, get_box._servo_overflow_clip_box,
+        get_position.z_index, get_box._servo_overflow_clip_box,
         get_inheritedtext._servo_text_decorations_in_effect,
         get_pointing.cursor, get_pointing.pointer_events,
-        get_effects.box_shadow, get_effects.clip, get_effects.text_shadow, get_effects.filter,
+        get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter,
         get_effects.transform, get_effects.backface_visibility, get_effects.transform_style,
         get_effects.transform_origin, get_effects.perspective, get_effects.perspective_origin,
         get_effects.mix_blend_mode, get_inheritedbox.image_rendering,
 
         // Note: May require REFLOW et al. if `visibility: collapse` is implemented.
         get_inheritedbox.visibility
     ]);
 
--- a/servo/components/layout/inline.rs
+++ b/servo/components/layout/inline.rs
@@ -666,17 +666,17 @@ impl LineBreaker {
             self.pending_line.range.reset(FragmentIndex(self.new_fragments.len() as isize),
                                           FragmentIndex(0));
         }
 
         // Determine if an ellipsis will be necessary to account for `text-overflow`.
         let mut need_ellipsis = false;
         let available_inline_size = self.pending_line.green_zone.inline -
             self.pending_line.bounds.size.inline - indentation;
-        match (fragment.style().get_inheritedtext().text_overflow,
+        match (fragment.style().get_text().text_overflow,
                fragment.style().get_box().overflow_x) {
             (text_overflow::T::clip, _) | (_, overflow_x::T::visible) => {}
             (text_overflow::T::ellipsis, _) => {
                 need_ellipsis = fragment.margin_box_inline_size() > available_inline_size;
             }
         }
 
         if !need_ellipsis {
--- a/servo/components/layout/text.rs
+++ b/servo/components/layout/text.rs
@@ -412,17 +412,17 @@ pub fn font_metrics_for_style(font_conte
     // FIXME(https://github.com/rust-lang/rust/issues/23338)
     let font = fontgroup.fonts[0].borrow();
     font.metrics.clone()
 }
 
 /// Returns the line block-size needed by the given computed style and font size.
 pub fn line_height_from_style(style: &ServoComputedValues, metrics: &FontMetrics) -> Au {
     let font_size = style.get_font().font_size;
-    match style.get_inheritedbox().line_height {
+    match style.get_inheritedtext().line_height {
         line_height::T::Normal => metrics.line_gap,
         line_height::T::Number(l) => font_size.scale_by(l),
         line_height::T::Length(l) => l
     }
 }
 
 fn split_first_fragment_at_newline_if_necessary(fragments: &mut LinkedList<Fragment>) {
     if fragments.is_empty() {
--- a/servo/components/layout/wrapper.rs
+++ b/servo/components/layout/wrapper.rs
@@ -1029,17 +1029,17 @@ impl<'ln> ThreadSafeLayoutNode for Servo
             let data = &self.borrow_layout_data().unwrap().style_data;
 
             let style = if self.pseudo.is_before() {
                 data.per_pseudo.get(&PseudoElement::Before).unwrap()
             } else {
                 data.per_pseudo.get(&PseudoElement::After).unwrap()
             };
 
-            return match style.as_ref().get_box().content {
+            return match style.as_ref().get_counters().content {
                 content::T::Content(ref value) if !value.is_empty() => {
                     TextContent::GeneratedContent((*value).clone())
                 }
                 _ => TextContent::GeneratedContent(vec![]),
             };
         }
 
         let this = unsafe { self.get_jsmanaged() };
--- a/servo/components/style/animation.rs
+++ b/servo/components/style/animation.rs
@@ -19,17 +19,17 @@ use properties::longhands::transform::co
 use properties::longhands::transform::computed_value::T as TransformList;
 use properties::longhands::transition_property;
 use properties::longhands::transition_property::computed_value::TransitionProperty;
 use properties::longhands::transition_timing_function::computed_value::{StartEnd};
 use properties::longhands::transition_timing_function::computed_value::{TransitionTimingFunction};
 use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
 use properties::longhands::visibility::computed_value::T as Visibility;
 use properties::longhands::z_index::computed_value::T as ZIndex;
-use properties::style_struct_traits::TAnimation;
+use properties::style_struct_traits::TBox;
 use properties::{ComputedValues, ServoComputedValues};
 use std::cmp::Ordering;
 use std::iter::repeat;
 use std::sync::mpsc::Sender;
 use std::sync::{Arc, Mutex};
 use time;
 use values::CSSFloat;
 use values::computed::{Angle, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
@@ -69,17 +69,17 @@ impl PropertyAnimation {
     /// Any number of animations may be returned, from zero (if the property did not animate) to
     /// one (for a single transition property) to arbitrarily many (for `all`).
     pub fn from_transition(transition_index: usize,
                            old_style: &ServoComputedValues,
                            new_style: &mut ServoComputedValues)
                            -> Vec<PropertyAnimation> {
         let mut result = Vec::new();
         let transition_property =
-            new_style.as_servo().get_animation().transition_property.0[transition_index];
+            new_style.as_servo().get_box().transition_property.0[transition_index];
         if transition_property != TransitionProperty::All {
             if let Some(property_animation) =
                     PropertyAnimation::from_transition_property(transition_property,
                                                                 transition_index,
                                                                 old_style,
                                                                 new_style) {
                 result.push(property_animation)
             }
@@ -100,17 +100,17 @@ impl PropertyAnimation {
         result
     }
 
     fn from_transition_property(transition_property: TransitionProperty,
                                 transition_index: usize,
                                 old_style: &ServoComputedValues,
                                 new_style: &mut ServoComputedValues)
                                 -> Option<PropertyAnimation> {
-        let animation_style = new_style.get_animation();
+        let box_style = new_style.get_box();
         macro_rules! match_transition {
                 ( $( [$name:ident; $structname:ident; $field:ident] ),* ) => {
                     match transition_property {
                         TransitionProperty::All => {
                             panic!("Don't use `TransitionProperty::All` with \
                                    `PropertyAnimation::from_transition_property`!")
                         }
                         $(
@@ -123,18 +123,18 @@ impl PropertyAnimation {
                             AnimatedProperty::Clip(old_style.get_effects().clip.0,
                                                    new_style.get_effects().clip.0)
                         }
                         TransitionProperty::LetterSpacing => {
                             AnimatedProperty::LetterSpacing(old_style.get_inheritedtext().letter_spacing.0,
                                                             new_style.get_inheritedtext().letter_spacing.0)
                         }
                         TransitionProperty::TextShadow => {
-                            AnimatedProperty::TextShadow(old_style.get_effects().text_shadow.clone(),
-                                                         new_style.get_effects().text_shadow.clone())
+                            AnimatedProperty::TextShadow(old_style.get_inheritedtext().text_shadow.clone(),
+                                                         new_style.get_inheritedtext().text_shadow.clone())
                         }
                         TransitionProperty::Transform => {
                             AnimatedProperty::Transform(old_style.get_effects().transform.clone(),
                                                         new_style.get_effects().transform.clone())
                         }
                         TransitionProperty::WordSpacing => {
                             AnimatedProperty::WordSpacing(old_style.get_inheritedtext().word_spacing.0,
                                                           new_style.get_inheritedtext().word_spacing.0)
@@ -149,51 +149,51 @@ impl PropertyAnimation {
             [BorderBottomWidth; get_border; border_bottom_width],
             [BorderLeftColor; get_border; border_left_color],
             [BorderLeftWidth; get_border; border_left_width],
             [BorderRightColor; get_border; border_right_color],
             [BorderRightWidth; get_border; border_right_width],
             [BorderSpacing; get_inheritedtable; border_spacing],
             [BorderTopColor; get_border; border_top_color],
             [BorderTopWidth; get_border; border_top_width],
-            [Bottom; get_positionoffsets; bottom],
+            [Bottom; get_position; bottom],
             [Color; get_color; color],
             [FontSize; get_font; font_size],
             [FontWeight; get_font; font_weight],
             [Height; get_box; height],
-            [Left; get_positionoffsets; left],
-            [LineHeight; get_inheritedbox; line_height],
+            [Left; get_position; left],
+            [LineHeight; get_inheritedtext; line_height],
             [MarginBottom; get_margin; margin_bottom],
             [MarginLeft; get_margin; margin_left],
             [MarginRight; get_margin; margin_right],
             [MarginTop; get_margin; margin_top],
-            [MaxHeight; get_box; max_height],
-            [MaxWidth; get_box; max_width],
-            [MinHeight; get_box; min_height],
-            [MinWidth; get_box; min_width],
+            [MaxHeight; get_position; max_height],
+            [MaxWidth; get_position; max_width],
+            [MinHeight; get_position; min_height],
+            [MinWidth; get_position; min_width],
             [Opacity; get_effects; opacity],
             [OutlineColor; get_outline; outline_color],
             [OutlineWidth; get_outline; outline_width],
             [PaddingBottom; get_padding; padding_bottom],
             [PaddingLeft; get_padding; padding_left],
             [PaddingRight; get_padding; padding_right],
             [PaddingTop; get_padding; padding_top],
-            [Right; get_positionoffsets; right],
+            [Right; get_position; right],
             [TextIndent; get_inheritedtext; text_indent],
-            [Top; get_positionoffsets; top],
+            [Top; get_position; top],
             [VerticalAlign; get_box; vertical_align],
             [Visibility; get_inheritedbox; visibility],
             [Width; get_box; width],
-            [ZIndex; get_box; z_index]);
+            [ZIndex; get_position; z_index]);
 
         let property_animation = PropertyAnimation {
             property: animated_property,
             timing_function:
-                *animation_style.transition_timing_function.0.get_mod(transition_index),
-            duration: *animation_style.transition_duration.0.get_mod(transition_index),
+                *box_style.transition_timing_function.0.get_mod(transition_index),
+            duration: *box_style.transition_duration.0.get_mod(transition_index),
         };
         if property_animation.does_not_animate() {
             None
         } else {
             Some(property_animation)
         }
     }
 
@@ -247,47 +247,47 @@ impl PropertyAnimation {
             [BorderBottomWidth; mutate_border; border_bottom_width],
             [BorderLeftColor; mutate_border; border_left_color],
             [BorderLeftWidth; mutate_border; border_left_width],
             [BorderRightColor; mutate_border; border_right_color],
             [BorderRightWidth; mutate_border; border_right_width],
             [BorderSpacing; mutate_inheritedtable; border_spacing],
             [BorderTopColor; mutate_border; border_top_color],
             [BorderTopWidth; mutate_border; border_top_width],
-            [Bottom; mutate_positionoffsets; bottom],
+            [Bottom; mutate_position; bottom],
             [Color; mutate_color; color],
             [FontSize; mutate_font; font_size],
             [FontWeight; mutate_font; font_weight],
             [Height; mutate_box; height],
-            [Left; mutate_positionoffsets; left],
-            [LineHeight; mutate_inheritedbox; line_height],
+            [Left; mutate_position; left],
+            [LineHeight; mutate_inheritedtext; line_height],
             [MarginBottom; mutate_margin; margin_bottom],
             [MarginLeft; mutate_margin; margin_left],
             [MarginRight; mutate_margin; margin_right],
             [MarginTop; mutate_margin; margin_top],
-            [MaxHeight; mutate_box; max_height],
-            [MaxWidth; mutate_box; max_width],
-            [MinHeight; mutate_box; min_height],
-            [MinWidth; mutate_box; min_width],
+            [MaxHeight; mutate_position; max_height],
+            [MaxWidth; mutate_position; max_width],
+            [MinHeight; mutate_position; min_height],
+            [MinWidth; mutate_position; min_width],
             [Opacity; mutate_effects; opacity],
             [OutlineColor; mutate_outline; outline_color],
             [OutlineWidth; mutate_outline; outline_width],
             [PaddingBottom; mutate_padding; padding_bottom],
             [PaddingLeft; mutate_padding; padding_left],
             [PaddingRight; mutate_padding; padding_right],
             [PaddingTop; mutate_padding; padding_top],
-            [Right; mutate_positionoffsets; right],
+            [Right; mutate_position; right],
             [TextIndent; mutate_inheritedtext; text_indent],
-            [TextShadow; mutate_effects; text_shadow],
-            [Top; mutate_positionoffsets; top],
+            [TextShadow; mutate_inheritedtext; text_shadow],
+            [Top; mutate_position; top],
             [Transform; mutate_effects; transform],
             [VerticalAlign; mutate_box; vertical_align],
             [Visibility; mutate_inheritedbox; visibility],
             [Width; mutate_box; width],
-            [ZIndex; mutate_box; z_index]);
+            [ZIndex; mutate_position; z_index]);
     }
 
     #[inline]
     fn does_not_animate(&self) -> bool {
         self.property.does_not_animate() || self.duration == Time(0.0)
     }
 }
 
@@ -931,34 +931,34 @@ impl<T> GetMod for Vec<T> {
 /// difference. This is called from the layout worker threads. Returns true if any animations were
 /// kicked off and false otherwise.
 pub fn start_transitions_if_applicable<C: ComputedValues>(new_animations_sender: &Mutex<Sender<Animation>>,
                                                           node: OpaqueNode,
                                                           old_style: &C,
                                                           new_style: &mut C)
                                                           -> bool {
     let mut had_animations = false;
-    for i in 0..new_style.get_animation().transition_count() {
+    for i in 0..new_style.get_box().transition_count() {
         // Create any property animations, if applicable.
         let property_animations = PropertyAnimation::from_transition(i, old_style.as_servo(), new_style.as_servo_mut());
         for property_animation in property_animations {
             // Set the property to the initial value.
             property_animation.update(new_style.as_servo_mut(), 0.0);
 
             // Kick off the animation.
             let now = time::precise_time_s();
-            let animation_style = new_style.as_servo().get_animation();
+            let box_style = new_style.as_servo().get_box();
             let start_time =
-                now + (animation_style.transition_delay.0.get_mod(i).seconds() as f64);
+                now + (box_style.transition_delay.0.get_mod(i).seconds() as f64);
             new_animations_sender.lock().unwrap().send(Animation {
                 node: node,
                 property_animation: property_animation,
                 start_time: start_time,
                 end_time: start_time +
-                    (animation_style.transition_duration.0.get_mod(i).seconds() as f64),
+                    (box_style.transition_duration.0.get_mod(i).seconds() as f64),
             }).unwrap();
 
             had_animations = true
         }
     }
 
     had_animations
 }
--- a/servo/components/style/properties.mako.rs
+++ b/servo/components/style/properties.mako.rs
@@ -455,33 +455,34 @@ pub mod longhands {
             fn to_computed_value<Cx: TContext>(&self, context: &Cx) -> computed_value::T {
                 self.0.to_computed_value(context)
             }
         }
     </%self:longhand>
 
     ${predefined_type("outline-offset", "Length", "Au(0)")}
 
-    ${new_style_struct("PositionOffsets", is_inherited=False, gecko_name="nsStylePosition")}
+    ${new_style_struct("Position", is_inherited=False, gecko_name="nsStylePosition")}
 
     % for side in ["top", "right", "bottom", "left"]:
         ${predefined_type(side, "LengthOrPercentageOrAuto",
                           "computed::LengthOrPercentageOrAuto::Auto")}
     % endfor
 
     // CSS 2.1, Section 9 - Visual formatting model
 
     ${new_style_struct("Box", is_inherited=False, gecko_name="nsStyleDisplay",
                        additional_methods=[Method("clone_display",
                                                   "longhands::display::computed_value::T"),
                                            Method("clone_position",
                                                   "longhands::position::computed_value::T"),
                                            Method("is_floated", "bool"),
                                            Method("overflow_x_is_visible", "bool"),
-                                           Method("overflow_y_is_visible", "bool")])}
+                                           Method("overflow_y_is_visible", "bool"),
+                                           Method("transition_count", "usize")])}
 
     // TODO(SimonSapin): don't parse `inline-table`, since we don't support it
     <%self:longhand name="display" custom_cascade="True">
         <%
             values = """inline block inline-block
                 table inline-table table-row-group table-header-group table-footer-group
                 table-row table-column-group table-column table-cell table-caption
                 list-item flex
@@ -583,16 +584,18 @@ pub mod longhands {
         #[inline]
         pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
             let d = context.style().get_box().clone_display();
             context.mutate_style().mutate_box().set__servo_display_for_hypothetical_box(d);
         }
 
     </%self:longhand>
 
+    ${switch_to_style_struct("Position")}
+
     <%self:longhand name="z-index">
         use values::computed::ComputedValueAsSpecified;
 
         impl ComputedValueAsSpecified for SpecifiedValue {}
         pub type SpecifiedValue = computed_value::T;
         pub mod computed_value {
             use cssparser::ToCss;
             use std::fmt;
@@ -651,31 +654,35 @@ pub mod longhands {
     ${predefined_type("width", "LengthOrPercentageOrAuto",
                       "computed::LengthOrPercentageOrAuto::Auto",
                       "parse_non_negative")}
 
     ${predefined_type("height", "LengthOrPercentageOrAuto",
                       "computed::LengthOrPercentageOrAuto::Auto",
                       "parse_non_negative")}
 
+    ${switch_to_style_struct("Position")}
+
     ${predefined_type("min-width", "LengthOrPercentage",
                       "computed::LengthOrPercentage::Length(Au(0))",
                       "parse_non_negative")}
     ${predefined_type("max-width", "LengthOrPercentageOrNone",
                       "computed::LengthOrPercentageOrNone::None",
                       "parse_non_negative")}
 
     ${predefined_type("min-height", "LengthOrPercentage",
                       "computed::LengthOrPercentage::Length(Au(0))",
                       "parse_non_negative")}
     ${predefined_type("max-height", "LengthOrPercentageOrNone",
                       "computed::LengthOrPercentageOrNone::None",
                       "parse_non_negative")}
 
-    ${switch_to_style_struct("InheritedBox")}
+    ${new_style_struct("InheritedText", is_inherited=True, gecko_name="nsStyleText",
+                       additional_methods=[Method("clone__servo_text_decorations_in_effect",
+                                                  "longhands::_servo_text_decorations_in_effect::computed_value::T")])}
 
     <%self:longhand name="line-height">
         use cssparser::ToCss;
         use std::fmt;
         use values::AuExtensionMethods;
         use values::CSSFloat;
 
         #[derive(Debug, Clone, PartialEq, Copy, HeapSizeOf)]
@@ -899,17 +906,17 @@ pub mod longhands {
 
     ${switch_to_style_struct("InheritedBox")}
 
     // TODO: collapse. Well, do tables first.
     ${single_keyword("visibility", "visible hidden")}
 
     // CSS 2.1, Section 12 - Generated content, automatic numbering, and lists
 
-    ${switch_to_style_struct("Box")}
+    ${new_style_struct("Counters", is_inherited=False)}
 
     <%self:longhand name="content">
         use cssparser::Token;
         use std::ascii::AsciiExt;
         use values::computed::ComputedValueAsSpecified;
 
         use super::list_style_type;
 
@@ -1212,17 +1219,17 @@ pub mod longhands {
             if !quotes.is_empty() {
                 Ok(SpecifiedValue(quotes))
             } else {
                 Err(())
             }
         }
     </%self:longhand>
 
-    ${new_style_struct("Counters", is_inherited=False)}
+    ${switch_to_style_struct("Counters")}
 
     <%self:longhand name="counter-increment">
         use std::fmt;
         use super::content;
         use values::computed::ComputedValueAsSpecified;
 
         use cssparser::{ToCss, Token, serialize_identifier};
         use std::borrow::{Cow, ToOwned};
@@ -1968,19 +1975,17 @@ pub mod longhands {
     </%self:longhand>
 
     ${single_keyword("font-stretch",
                      "normal ultra-condensed extra-condensed condensed semi-condensed semi-expanded \
                      expanded extra-expanded ultra-expanded")}
 
     // CSS 2.1, Section 16 - Text
 
-    ${new_style_struct("InheritedText", is_inherited=True, gecko_name="nsStyleText",
-                       additional_methods=[Method("clone__servo_text_decorations_in_effect",
-                                                  "longhands::_servo_text_decorations_in_effect::computed_value::T")])}
+    ${switch_to_style_struct("InheritedText")}
 
     <%self:longhand name="text-align">
         pub use self::computed_value::T as SpecifiedValue;
         use values::computed::ComputedValueAsSpecified;
         impl ComputedValueAsSpecified for SpecifiedValue {}
         pub mod computed_value {
             macro_rules! define_text_align {
                 ( $( $name: ident ( $string: expr ) => $discriminant: expr, )+ ) => {
@@ -2157,26 +2162,26 @@ pub mod longhands {
 
     // Also known as "word-wrap" (which is more popular because of IE), but this is the preferred
     // name per CSS-TEXT 6.2.
     ${single_keyword("overflow-wrap", "normal break-word")}
 
     // TODO(pcwalton): Support `word-break: keep-all` once we have better CJK support.
     ${single_keyword("word-break", "normal break-all")}
 
-    ${single_keyword("text-overflow", "clip ellipsis")}
-
     // TODO(pcwalton): Support `text-justify: distribute`.
     ${single_keyword("text-justify", "auto none inter-word")}
 
     ${new_style_struct("Text", is_inherited=False, gecko_name="nsStyleTextReset",
                        additional_methods=[Method("has_underline", "bool"),
                                            Method("has_overline", "bool"),
                                            Method("has_line_through", "bool")])}
 
+    ${single_keyword("text-overflow", "clip ellipsis")}
+
     ${single_keyword("unicode-bidi", "normal embed isolate bidi-override isolate-override plaintext")}
 
     <%self:longhand name="text-decoration" custom_cascade="True">
         use cssparser::ToCss;
         use std::fmt;
         use values::computed::ComputedValueAsSpecified;
         use properties::style_struct_traits::TInheritedText;
 
@@ -2504,17 +2509,17 @@ pub mod longhands {
     ${single_keyword("writing-mode", "horizontal-tb vertical-rl vertical-lr", experimental=True)}
 
     // FIXME(SimonSapin): Add 'mixed' and 'upright' (needs vertical text support)
     // FIXME(SimonSapin): initial (first) value should be 'mixed', when that's implemented
     ${single_keyword("text-orientation", "sideways sideways-left sideways-right", experimental=True)}
 
     // CSS Basic User Interface Module Level 3
     // http://dev.w3.org/csswg/css-ui/
-    ${switch_to_style_struct("Box")}
+    ${switch_to_style_struct("Position")}
 
     ${single_keyword("box-sizing", "content-box border-box")}
 
     ${new_style_struct("Pointing", is_inherited=True)}
 
     <%self:longhand name="cursor">
         pub use self::computed_value::T as SpecifiedValue;
         use values::computed::ComputedValueAsSpecified;
@@ -3156,16 +3161,18 @@ pub mod longhands {
                     left: sides[3].unwrap_or(Length::Absolute(Au(0))),
                 })))
             } else {
                 Err(())
             }
         }
     </%self:longhand>
 
+    ${switch_to_style_struct("InheritedText")}
+
     <%self:longhand name="text-shadow">
         use cssparser::{self, ToCss};
         use std::fmt;
         use values::AuExtensionMethods;
 
         #[derive(Clone, PartialEq, Debug, HeapSizeOf)]
         pub struct SpecifiedValue(Vec<SpecifiedTextShadow>);
 
@@ -3334,16 +3341,18 @@ pub mod longhands {
                                     .map(|color| color.parsed)
                                     .unwrap_or(cssparser::Color::CurrentColor),
                     }
                 }).collect())
             }
         }
     </%self:longhand>
 
+    ${switch_to_style_struct("Effects")}
+
     <%self:longhand name="filter">
         //pub use self::computed_value::T as SpecifiedValue;
         use cssparser::ToCss;
         use std::fmt;
         use values::AuExtensionMethods;
         use values::CSSFloat;
         use values::specified::{Angle, Length};
 
@@ -4322,18 +4331,17 @@ pub mod longhands {
 
             #[inline]
             fn to_computed_value<Cx: TContext>(&self, _: &Cx) -> computed_value::T {
                 *self
             }
         }
     </%self:longhand>
 
-    ${new_style_struct("Animation", is_inherited=False,
-                       additional_methods=[Method("transition_count", return_type="usize")])}
+    ${switch_to_style_struct("Box")}
 
     // TODO(pcwalton): Multiple transitions.
     <%self:longhand name="transition-duration">
         use values::specified::Time;
 
         pub use self::computed_value::T as SpecifiedValue;
         pub use values::specified::Time as SingleSpecifiedValue;
 
@@ -4849,17 +4857,17 @@ pub mod longhands {
         pub use properties::longhands::transition_duration::{computed_value};
         pub use properties::longhands::transition_duration::{get_initial_single_value};
         pub use properties::longhands::transition_duration::{get_initial_value, parse, parse_one};
     </%self:longhand>
 
     // CSS Flexible Box Layout Module Level 1
     // http://www.w3.org/TR/css3-flexbox/
 
-    ${new_style_struct("Flex", is_inherited=False)}
+    ${switch_to_style_struct("Position")}
 
     // Flex container properties
     ${single_keyword("flex-direction", "row row-reverse column column-reverse", experimental=True)}
 }
 
 
 pub mod shorthands {
     use cssparser::Parser;
@@ -6169,21 +6177,17 @@ pub mod style_structs {
             % for longhand in style_struct.longhands:
                 fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
                     self.${longhand.ident} = v;
                 }
                 fn copy_${longhand.ident}_from(&mut self, other: &Self) {
                     self.${longhand.ident} = other.${longhand.ident}.clone();
                 }
             % endfor
-            % if style_struct.name == "Animation":
-                fn transition_count(&self) -> usize {
-                    self.transition_property.0.len()
-                }
-            % elif style_struct.name == "Border":
+            % if style_struct.name == "Border":
                 % for side in ["top", "right", "bottom", "left"]:
                 fn border_${side}_is_none_or_hidden_and_has_nonzero_width(&self) -> bool {
                     self.border_${side}_style.none_or_hidden() &&
                     self.border_${side}_width != ::app_units::Au(0)
                 }
                 % endfor
             % elif style_struct.name == "Box":
                 fn clone_display(&self) -> longhands::display::computed_value::T {
@@ -6196,16 +6200,19 @@ pub mod style_structs {
                     self.float != longhands::float::SpecifiedValue::none
                 }
                 fn overflow_x_is_visible(&self) -> bool {
                     self.overflow_x == longhands::overflow_x::computed_value::T::visible
                 }
                 fn overflow_y_is_visible(&self) -> bool {
                     self.overflow_y.0 == longhands::overflow_x::computed_value::T::visible
                 }
+                fn transition_count(&self) -> usize {
+                    self.transition_property.0.len()
+                }
             % elif style_struct.name == "Color":
                 fn clone_color(&self) -> longhands::color::computed_value::T {
                     self.color.clone()
                 }
             % elif style_struct.name == "Font":
                 fn clone_font_size(&self) -> longhands::font_size::computed_value::T {
                     self.font_size.clone()
                 }
@@ -6397,36 +6404,36 @@ impl ServoComputedValues {
     #[inline]
     pub fn content_block_size(&self) -> computed::LengthOrPercentageOrAuto {
         let box_style = self.get_box();
         if self.writing_mode.is_vertical() { box_style.width } else { box_style.height }
     }
 
     #[inline]
     pub fn min_inline_size(&self) -> computed::LengthOrPercentage {
-        let box_style = self.get_box();
-        if self.writing_mode.is_vertical() { box_style.min_height } else { box_style.min_width }
+        let position_style = self.get_position();
+        if self.writing_mode.is_vertical() { position_style.min_height } else { position_style.min_width }
     }
 
     #[inline]
     pub fn min_block_size(&self) -> computed::LengthOrPercentage {
-        let box_style = self.get_box();
-        if self.writing_mode.is_vertical() { box_style.min_width } else { box_style.min_height }
+        let position_style = self.get_position();
+        if self.writing_mode.is_vertical() { position_style.min_width } else { position_style.min_height }
     }
 
     #[inline]
     pub fn max_inline_size(&self) -> computed::LengthOrPercentageOrNone {
-        let box_style = self.get_box();
-        if self.writing_mode.is_vertical() { box_style.max_height } else { box_style.max_width }
+        let position_style = self.get_position();
+        if self.writing_mode.is_vertical() { position_style.max_height } else { position_style.max_width }
     }
 
     #[inline]
     pub fn max_block_size(&self) -> computed::LengthOrPercentageOrNone {
-        let box_style = self.get_box();
-        if self.writing_mode.is_vertical() { box_style.max_width } else { box_style.max_height }
+        let position_style = self.get_position();
+        if self.writing_mode.is_vertical() { position_style.max_width } else { position_style.max_height }
     }
 
     #[inline]
     pub fn logical_padding(&self) -> LogicalMargin<computed::LengthOrPercentage> {
         let padding_style = self.get_padding();
         LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
             padding_style.padding_top,
             padding_style.padding_right,
@@ -6455,17 +6462,17 @@ impl ServoComputedValues {
             margin_style.margin_bottom,
             margin_style.margin_left,
         ))
     }
 
     #[inline]
     pub fn logical_position(&self) -> LogicalMargin<computed::LengthOrPercentageOrAuto> {
         // FIXME(SimonSapin): should be the writing mode of the containing block, maybe?
-        let position_style = self.get_positionoffsets();
+        let position_style = self.get_position();
         LogicalMargin::from_physical(self.writing_mode, SideOffsets2D::new(
             position_style.top,
             position_style.right,
             position_style.bottom,
             position_style.left,
         ))
     }
 
@@ -7067,21 +7074,21 @@ pub fn modify_style_for_outer_inline_blo
 /// Text is never directly relatively positioned; it's always contained within an element that is
 /// itself relatively positioned.
 #[inline]
 pub fn modify_style_for_text(style: &mut Arc<ServoComputedValues>) {
     if style.box_.position == longhands::position::computed_value::T::relative {
         // We leave the `position` property set to `relative` so that we'll still establish a
         // containing block if needed. But we reset all position offsets to `auto`.
         let mut style = Arc::make_mut(style);
-        let mut position_offsets = Arc::make_mut(&mut style.positionoffsets);
-        position_offsets.top = computed::LengthOrPercentageOrAuto::Auto;
-        position_offsets.right = computed::LengthOrPercentageOrAuto::Auto;
-        position_offsets.bottom = computed::LengthOrPercentageOrAuto::Auto;
-        position_offsets.left = computed::LengthOrPercentageOrAuto::Auto;
+        let mut position = Arc::make_mut(&mut style.position);
+        position.top = computed::LengthOrPercentageOrAuto::Auto;
+        position.right = computed::LengthOrPercentageOrAuto::Auto;
+        position.bottom = computed::LengthOrPercentageOrAuto::Auto;
+        position.left = computed::LengthOrPercentageOrAuto::Auto;
     }
 
     if style.padding.padding_top != computed::LengthOrPercentage::Length(Au(0)) ||
             style.padding.padding_right != computed::LengthOrPercentage::Length(Au(0)) ||
             style.padding.padding_bottom != computed::LengthOrPercentage::Length(Au(0)) ||
             style.padding.padding_left != computed::LengthOrPercentage::Length(Au(0)) {
         let mut style = Arc::make_mut(style);
         let mut padding = Arc::make_mut(&mut style.padding);