layout: Fix several bugs relating to inline borders, padding, and

margins.

* The code that attempted to strip out borders that span multiple
  fragments in the same element could go wrong if fragments were
  stripped out due to text clumping or whitespace stripping. This patch
  rewrites that code to maintain flags in the inline fragment context
  specifying whether the node is the beginning or end of the element.
  Not only is this easier to maintain, it's closer in spirit to what roc
  originally suggested two years ago: it's isomorphic to "begin element,
  end element" markers for inline layout.

* Padding and margins for spans containing inline-blocks are now
  properly handled via a division of labor between the `InlineBlock`
  fragment and the `BlockFlow` that represents the inline-block.

* Unscanned text fragments may not be joined together into a text run if
  borders, padding, or margins separate them.

Because Servo now matches the rendering of Gecko and WebKit on the
`input_button_margins_a` reftest, I had to modify it to add some
vertical alignment.

The combined effect of all of these fixes places "Advertising" on the
right place on google.com.
This commit is contained in:
Patrick Walton 2015-08-13 09:49:40 -07:00
parent 3f9b6f8586
commit ee8741b7a8
11 changed files with 319 additions and 130 deletions

View file

@ -6456,15 +6456,15 @@ pub fn modify_style_for_replaced_content(style: &mut Arc<ComputedValues>) {
}
}
/// Adjusts borders, padding, and margins as appropriate to account for a fragment's status as the
/// first or last fragment within the range of an element.
/// Adjusts borders as appropriate to account for a fragment's status as the first or last fragment
/// within the range of an element.
///
/// Specifically, this function sets border/padding/margin widths to zero on the sides for which
/// the fragment is not outermost.
/// Specifically, this function sets border widths to zero on the sides for which the fragment is
/// not outermost.
#[inline]
pub fn modify_style_for_inline_sides(style: &mut Arc<ComputedValues>,
is_first_fragment_of_element: bool,
is_last_fragment_of_element: bool) {
pub fn modify_border_style_for_inline_sides(style: &mut Arc<ComputedValues>,
is_first_fragment_of_element: bool,
is_last_fragment_of_element: bool) {
fn modify_side(style: &mut Arc<ComputedValues>, side: PhysicalSide) {
let mut style = Arc::make_mut(style);
let border = Arc::make_mut(&mut style.border);
@ -6472,34 +6472,18 @@ pub fn modify_style_for_inline_sides(style: &mut Arc<ComputedValues>,
PhysicalSide::Left => {
border.border_left_width = Au(0);
border.border_left_style = BorderStyle::none;
Arc::make_mut(&mut style.padding).padding_left =
computed::LengthOrPercentage::Length(Au(0));
Arc::make_mut(&mut style.margin).margin_left =
computed::LengthOrPercentageOrAuto::Length(Au(0))
}
PhysicalSide::Right => {
border.border_right_width = Au(0);
border.border_right_style = BorderStyle::none;
Arc::make_mut(&mut style.padding).padding_right =
computed::LengthOrPercentage::Length(Au(0));
Arc::make_mut(&mut style.margin).margin_right =
computed::LengthOrPercentageOrAuto::Length(Au(0))
}
PhysicalSide::Bottom => {
border.border_bottom_width = Au(0);
border.border_bottom_style = BorderStyle::none;
Arc::make_mut(&mut style.padding).padding_bottom =
computed::LengthOrPercentage::Length(Au(0));
Arc::make_mut(&mut style.margin).margin_bottom =
computed::LengthOrPercentageOrAuto::Length(Au(0))
}
PhysicalSide::Top => {
border.border_top_width = Au(0);
border.border_top_style = BorderStyle::none;
Arc::make_mut(&mut style.padding).padding_top =
computed::LengthOrPercentage::Length(Au(0));
Arc::make_mut(&mut style.margin).margin_top =
computed::LengthOrPercentageOrAuto::Length(Au(0))
}
}
}
@ -6534,7 +6518,7 @@ pub fn modify_style_for_outer_inline_block_fragment(style: &mut Arc<ComputedValu
box_style.position = longhands::position::computed_value::T::static_
}
/// Adjusts the `position` property as necessary to account for text.
/// Adjusts the `position` and `padding` properties as necessary to account for text.
///
/// Text is never directly relatively positioned; it's always contained within an element that is
/// itself relatively positioned.
@ -6550,6 +6534,18 @@ pub fn modify_style_for_text(style: &mut Arc<ComputedValues>) {
position_offsets.bottom = computed::LengthOrPercentageOrAuto::Auto;
position_offsets.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_unique(style);
let mut padding = Arc::make_unique(&mut style.padding);
padding.padding_top = computed::LengthOrPercentage::Length(Au(0));
padding.padding_right = computed::LengthOrPercentage::Length(Au(0));
padding.padding_bottom = computed::LengthOrPercentage::Length(Au(0));
padding.padding_left = computed::LengthOrPercentage::Length(Au(0));
}
}
/// Adjusts the `margin` property as necessary to account for the text of an `input` element.