layout: Use a special path that treats margin: auto as zero for inline-block

inline size computation.

Places the search icon in the right place on the Google SERPs.
This commit is contained in:
Patrick Walton 2015-09-03 15:35:32 -07:00
parent aeb8dce2d9
commit 683290e109
7 changed files with 196 additions and 9 deletions

View file

@ -505,6 +505,8 @@ pub enum BlockType {
AbsoluteNonReplaced,
FloatReplaced,
FloatNonReplaced,
InlineBlockReplaced,
InlineBlockNonReplaced,
}
#[derive(Clone, PartialEq)]
@ -614,6 +616,12 @@ impl BlockFlow {
} else {
BlockType::FloatNonReplaced
}
} else if self.is_inline_block() {
if self.is_replaced_content() {
BlockType::InlineBlockReplaced
} else {
BlockType::InlineBlockNonReplaced
}
} else {
if self.is_replaced_content() {
BlockType::Replaced
@ -680,6 +688,18 @@ impl BlockFlow {
layout_context,
containing_block_inline_size);
}
BlockType::InlineBlockReplaced => {
let inline_size_computer = InlineBlockReplaced;
inline_size_computer.compute_used_inline_size(self,
layout_context,
containing_block_inline_size);
}
BlockType::InlineBlockNonReplaced => {
let inline_size_computer = InlineBlockNonReplaced;
inline_size_computer.compute_used_inline_size(self,
layout_context,
containing_block_inline_size);
}
BlockType::Replaced => {
let inline_size_computer = BlockReplaced;
inline_size_computer.compute_used_inline_size(self,
@ -2481,12 +2501,6 @@ pub trait ISizeAndMarginsComputer {
}
};
// If inline-size is set to 'auto', and this is an inline block, use the
// shrink to fit algorithm (see CSS 2.1 § 10.3.9)
if computed_inline_size == MaybeAuto::Auto && block.is_inline_block() {
inline_size = block.get_shrink_to_fit_inline_size(inline_size);
}
ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin)
}
}
@ -2501,6 +2515,8 @@ pub struct BlockNonReplaced;
pub struct BlockReplaced;
pub struct FloatNonReplaced;
pub struct FloatReplaced;
pub struct InlineBlockNonReplaced;
pub struct InlineBlockReplaced;
impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
/// Solve the horizontal constraint equation for absolute non-replaced elements.
@ -2899,3 +2915,91 @@ impl ISizeAndMarginsComputer for FloatReplaced {
MaybeAuto::Specified(fragment.content_inline_size())
}
}
impl ISizeAndMarginsComputer for InlineBlockNonReplaced {
/// Compute inline-start and inline-end margins and inline-size.
fn solve_inline_size_constraints(&self,
block: &mut BlockFlow,
input: &ISizeConstraintInput)
-> ISizeConstraintSolution {
let (mut computed_inline_size,
inline_start_margin,
inline_end_margin,
available_inline_size) =
(input.computed_inline_size,
input.inline_start_margin,
input.inline_end_margin,
input.available_inline_size);
// For inline-blocks, `auto` margins compute to 0.
let inline_start_margin = inline_start_margin.specified_or_zero();
let inline_end_margin = inline_end_margin.specified_or_zero();
// If inline-size is set to 'auto', and this is an inline block, use the
// shrink to fit algorithm (see CSS 2.1 § 10.3.9)
let inline_size = match computed_inline_size {
MaybeAuto::Auto => {
block.get_shrink_to_fit_inline_size(available_inline_size - (inline_start_margin +
inline_end_margin))
}
MaybeAuto::Specified(inline_size) => inline_size,
};
ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin)
}
}
impl ISizeAndMarginsComputer for InlineBlockReplaced {
/// Compute inline-start and inline-end margins and inline-size.
///
/// ISize has already been calculated. We now calculate the margins just
/// like for non-replaced blocks.
fn solve_inline_size_constraints(&self,
block: &mut BlockFlow,
input: &ISizeConstraintInput)
-> ISizeConstraintSolution {
debug_assert!(match input.computed_inline_size {
MaybeAuto::Specified(_) => true,
MaybeAuto::Auto => false,
});
let (mut computed_inline_size,
inline_start_margin,
inline_end_margin,
available_inline_size) =
(input.computed_inline_size,
input.inline_start_margin,
input.inline_end_margin,
input.available_inline_size);
// For inline-blocks, `auto` margins compute to 0.
let inline_start_margin = inline_start_margin.specified_or_zero();
let inline_end_margin = inline_end_margin.specified_or_zero();
// If inline-size is set to 'auto', and this is an inline block, use the
// shrink to fit algorithm (see CSS 2.1 § 10.3.9)
let inline_size = match computed_inline_size {
MaybeAuto::Auto => {
block.get_shrink_to_fit_inline_size(available_inline_size - (inline_start_margin +
inline_end_margin))
}
MaybeAuto::Specified(inline_size) => inline_size,
};
ISizeConstraintSolution::new(inline_size, inline_start_margin, inline_end_margin)
}
/// Calculate used value of inline-size just like we do for inline replaced elements.
fn initial_computed_inline_size(&self,
block: &mut BlockFlow,
parent_flow_inline_size: Au,
_: &LayoutContext)
-> MaybeAuto {
let fragment = block.fragment();
fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size);
// For replaced block flow, the rest of the constraint solving will
// take inline-size to be specified as the value computed here.
MaybeAuto::Specified(fragment.content_inline_size())
}
}

View file

@ -168,6 +168,8 @@ prefs:"layout.writing-mode.enabled" == iframe/size_attributes_vertical_writing_m
== inline_block_border_intrinsic_size_a.html inline_block_border_intrinsic_size_ref.html
== inline_block_img_a.html inline_block_img_ref.html
== inline_block_margin_a.html inline_block_margin_ref.html
== inline_block_margin_auto_a.html inline_block_margin_auto_ref.html
== inline_block_margin_auto_zero_a.html inline_block_margin_auto_zero_ref.html
== inline_block_min_width.html inline_block_min_width_ref.html
== inline_block_overflow.html inline_block_overflow_ref.html
== inline_block_overflow_hidden_a.html inline_block_overflow_hidden_ref.html

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<style>
html, body {
margin: 0;
}
#a {
display: block;
background: lime;
text-align: center;
width: 96px;
}
#b {
background: gold;
display: inline-block;
margin: 0 auto;
padding: 16px 16px;
}
</style>
<div id=a><div id=b></div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<style>
html, body {
margin: 0;
}
#a {
display: block;
background: lime;
text-align: center;
width: 96px;
}
#b {
background: gold;
display: inline-block;
margin: 0 32px 0 32px;
padding: 16px 16px;
}
</style>
<div id=a><div id=b></div>

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<style>
html, body {
margin: 0;
}
section {
width: 300px;
height: 100px;
background: blue;
}
nav {
display: inline-block;
width: 100px;
height: 100px;
margin: 0 auto;
background: gold;
}
</style>
<section><nav></nav></section>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<style>
html, body {
margin: 0;
}
section {
position: absolute;
width: 100px;
height: 100px;
top: 0;
left: 0;
background: gold;
}
nav {
position: absolute;
width: 200px;
height: 100px;
top: 0;
left: 100px;
background: blue;
}
</style>
<section></section><nav></nav>

View file

@ -1,3 +0,0 @@
[inline-block-replaced-width-001.htm]
type: reftest
expected: FAIL