mirror of
https://github.com/servo/servo.git
synced 2025-06-23 08:34:42 +01:00
auto merge of #3615 : pcwalton/servo/box-sizing-fix, r=glennw
Improves GitHub significantly. r? @glennw
This commit is contained in:
commit
c87f34f877
5 changed files with 74 additions and 57 deletions
|
@ -26,7 +26,6 @@ use model::{Auto, IntrinsicISizes, MarginCollapseInfo, MarginsCollapse};
|
|||
use model::{MarginsCollapseThrough, MaybeAuto, NoCollapsibleMargins, Specified, specified};
|
||||
use model::{specified_or_none};
|
||||
use wrapper::ThreadSafeLayoutNode;
|
||||
use style::ComputedValues;
|
||||
use style::computed_values::{clear, position};
|
||||
|
||||
use collections::dlist::DList;
|
||||
|
@ -298,7 +297,7 @@ impl CandidateBSizeIterator {
|
|||
/// Creates a new candidate block-size iterator. `block_container_block-size` is `None` if the block-size
|
||||
/// of the block container has not been determined yet. It will always be `Some` in the case of
|
||||
/// absolutely-positioned containing blocks.
|
||||
pub fn new(style: &ComputedValues, block_container_block_size: Option<Au>)
|
||||
pub fn new(fragment: &Fragment, block_container_block_size: Option<Au>)
|
||||
-> CandidateBSizeIterator {
|
||||
// Per CSS 2.1 § 10.7, (assuming an horizontal writing mode,)
|
||||
// percentages in `min-height` and `max-height` refer to the height of
|
||||
|
@ -306,21 +305,21 @@ impl CandidateBSizeIterator {
|
|||
// If that is not determined yet by the time we need to resolve
|
||||
// `min-height` and `max-height`, percentage values are ignored.
|
||||
|
||||
let block_size = match (style.content_block_size(), block_container_block_size) {
|
||||
let block_size = match (fragment.style.content_block_size(), block_container_block_size) {
|
||||
(LPA_Percentage(percent), Some(block_container_block_size)) => {
|
||||
Specified(block_container_block_size.scale_by(percent))
|
||||
}
|
||||
(LPA_Percentage(_), None) | (LPA_Auto, _) => Auto,
|
||||
(LPA_Length(length), _) => Specified(length),
|
||||
};
|
||||
let max_block_size = match (style.max_block_size(), block_container_block_size) {
|
||||
let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) {
|
||||
(LPN_Percentage(percent), Some(block_container_block_size)) => {
|
||||
Some(block_container_block_size.scale_by(percent))
|
||||
}
|
||||
(LPN_Percentage(_), None) | (LPN_None, _) => None,
|
||||
(LPN_Length(length), _) => Some(length),
|
||||
};
|
||||
let min_block_size = match (style.min_block_size(), block_container_block_size) {
|
||||
let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) {
|
||||
(LP_Percentage(percent), Some(block_container_block_size)) => {
|
||||
block_container_block_size.scale_by(percent)
|
||||
}
|
||||
|
@ -328,12 +327,22 @@ impl CandidateBSizeIterator {
|
|||
(LP_Length(length), _) => length,
|
||||
};
|
||||
|
||||
CandidateBSizeIterator {
|
||||
block_size: block_size,
|
||||
max_block_size: max_block_size,
|
||||
min_block_size: min_block_size,
|
||||
// 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 {
|
||||
box_sizing::border_box => fragment.border_padding.block_start_end(),
|
||||
box_sizing::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),
|
||||
candidate_value: Au(0),
|
||||
status: InitialCandidateBSizeStatus,
|
||||
};
|
||||
|
||||
fn adjust(size: Au, delta: Au) -> Au {
|
||||
max(size - delta, Au(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -964,7 +973,7 @@ impl BlockFlow {
|
|||
// Compute any explicitly-specified block size.
|
||||
// Can't use `for` because we assign to `candidate_block_size_iterator.candidate_value`.
|
||||
let mut candidate_block_size_iterator = CandidateBSizeIterator::new(
|
||||
self.fragment.style(),
|
||||
&self.fragment,
|
||||
self.base.block_container_explicit_block_size);
|
||||
loop {
|
||||
match candidate_block_size_iterator.next() {
|
||||
|
@ -978,30 +987,14 @@ impl BlockFlow {
|
|||
}
|
||||
}
|
||||
|
||||
// Adjust `cur_b` as necessary to account for the explicitly-specified block-size.
|
||||
block_size = candidate_block_size_iterator.candidate_value;
|
||||
let delta = block_size - (cur_b - block_start_offset);
|
||||
translate_including_floats(&mut cur_b, delta, &mut floats);
|
||||
|
||||
match self.fragment.style().get_box().box_sizing {
|
||||
box_sizing::content_box => {
|
||||
// Adjust `cur_b` as necessary to account for the explicitly-specified block-size.
|
||||
block_size = candidate_block_size_iterator.candidate_value;
|
||||
let delta = block_size - (cur_b - block_start_offset);
|
||||
translate_including_floats(&mut cur_b, delta, &mut floats);
|
||||
|
||||
// Take border and padding into account.
|
||||
let block_end_offset = self.fragment.border_padding.block_end;
|
||||
translate_including_floats(&mut cur_b, block_end_offset, &mut floats);
|
||||
}
|
||||
box_sizing::border_box => {
|
||||
// Adjust `cur_b` as necessary to account for the explicitly-specified block-size.
|
||||
block_size = candidate_block_size_iterator.candidate_value;
|
||||
let delta = block_size - cur_b;
|
||||
translate_including_floats(&mut cur_b, delta, &mut floats);
|
||||
|
||||
// Take padding into account.
|
||||
let block_end_offset = self.fragment.border_padding.block_end -
|
||||
self.fragment.border_width().block_end;
|
||||
translate_including_floats(&mut cur_b, block_end_offset, &mut floats);
|
||||
}
|
||||
}
|
||||
// Take border and padding into account.
|
||||
let block_end_offset = self.fragment.border_padding.block_end;
|
||||
translate_including_floats(&mut cur_b, block_end_offset, &mut floats);
|
||||
|
||||
// Now that `cur_b` is at the block-end of the border box, compute the final border box
|
||||
// position.
|
||||
|
@ -1187,16 +1180,17 @@ impl BlockFlow {
|
|||
available_block_size,
|
||||
static_b_offset));
|
||||
} else {
|
||||
let style = self.fragment.style();
|
||||
let mut candidate_block_size_iterator =
|
||||
CandidateBSizeIterator::new(style, Some(containing_block_block_size));
|
||||
CandidateBSizeIterator::new(&self.fragment, Some(containing_block_block_size));
|
||||
|
||||
// Can't use `for` because we assign to candidate_block_size_iterator.candidate_value
|
||||
// Can't use `for` because we assign to
|
||||
// `candidate_block_size_iterator.candidate_value`.
|
||||
loop {
|
||||
match candidate_block_size_iterator.next() {
|
||||
Some(block_size_used_val) => {
|
||||
solution =
|
||||
Some(BSizeConstraintSolution::solve_vertical_constraints_abs_nonreplaced(
|
||||
Some(BSizeConstraintSolution::
|
||||
solve_vertical_constraints_abs_nonreplaced(
|
||||
block_size_used_val,
|
||||
margin_block_start,
|
||||
margin_block_end,
|
||||
|
@ -1222,12 +1216,7 @@ impl BlockFlow {
|
|||
|
||||
self.base.position.start.b = solution.block_start + self.fragment.margin.block_start;
|
||||
|
||||
let block_size = match self.fragment.style().get_box().box_sizing {
|
||||
box_sizing::content_box => {
|
||||
solution.block_size + self.fragment.border_padding.block_start_end()
|
||||
}
|
||||
box_sizing::border_box => solution.block_size,
|
||||
};
|
||||
let block_size = solution.block_size + self.fragment.border_padding.block_start_end();
|
||||
self.fragment.border_box.size.block = block_size;
|
||||
self.base.position.size.block = block_size;
|
||||
}
|
||||
|
@ -1914,16 +1903,27 @@ pub trait ISizeAndMarginsComputer {
|
|||
/// calculation involving min-inline-size and max-inline-size, we don't need to
|
||||
/// recompute these.
|
||||
fn compute_inline_size_constraint_inputs(&self,
|
||||
block: &mut BlockFlow,
|
||||
parent_flow_inline_size: Au,
|
||||
ctx: &LayoutContext)
|
||||
-> ISizeConstraintInput {
|
||||
let containing_block_inline_size = self.containing_block_inline_size(block, parent_flow_inline_size, ctx);
|
||||
let computed_inline_size = self.initial_computed_inline_size(block, parent_flow_inline_size, ctx);
|
||||
block: &mut BlockFlow,
|
||||
parent_flow_inline_size: Au,
|
||||
layout_context: &LayoutContext)
|
||||
-> ISizeConstraintInput {
|
||||
let containing_block_inline_size =
|
||||
self.containing_block_inline_size(block, parent_flow_inline_size, layout_context);
|
||||
|
||||
block.fragment.compute_border_padding_margins(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) {
|
||||
(Specified(size), box_sizing::border_box) => {
|
||||
computed_inline_size =
|
||||
Specified(size - block.fragment.border_padding.inline_start_end())
|
||||
}
|
||||
(Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {}
|
||||
}
|
||||
|
||||
// The text alignment of a block flow is the text alignment of its box's style.
|
||||
block.base.flags.set_text_align(style.get_inheritedtext().text_align);
|
||||
|
@ -1964,14 +1964,8 @@ pub trait ISizeAndMarginsComputer {
|
|||
fragment.border_box.start.i = fragment.margin.inline_start;
|
||||
|
||||
// The associated fragment has the border box of this flow.
|
||||
inline_size = match fragment.style().get_box().box_sizing {
|
||||
box_sizing::content_box => {
|
||||
solution.inline_size + fragment.border_padding.inline_start_end()
|
||||
}
|
||||
box_sizing::border_box => solution.inline_size,
|
||||
};
|
||||
|
||||
fragment.border_box.size.inline = inline_size;
|
||||
inline_size = solution.inline_size + fragment.border_padding.inline_start_end();
|
||||
fragment.border_box.size.inline = inline_size
|
||||
}
|
||||
|
||||
// We also resize the block itself, to ensure that overflow is not calculated
|
||||
|
|
|
@ -307,6 +307,14 @@ impl MaybeAuto {
|
|||
pub fn specified_or_zero(&self) -> Au {
|
||||
self.specified_or_default(Au::new(0))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto {
|
||||
match *self {
|
||||
Auto => Auto,
|
||||
Specified(value) => Specified(mapper(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
|
||||
|
|
|
@ -169,3 +169,4 @@ fragment=top != ../html/acid2.html acid2_ref.html
|
|||
!= input_height_a.html input_height_ref.html
|
||||
== pre_ignorable_whitespace_a.html pre_ignorable_whitespace_ref.html
|
||||
== many_brs_a.html many_brs_ref.html
|
||||
== box_sizing_sanity_check_a.html box_sizing_sanity_check_ref.html
|
||||
|
|
7
tests/ref/box_sizing_sanity_check_a.html
Normal file
7
tests/ref/box_sizing_sanity_check_a.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div style="box-sizing: border-box; float: left; background: yellow;">Heeheehee</div>
|
||||
</body>
|
||||
</html>
|
||||
|
7
tests/ref/box_sizing_sanity_check_ref.html
Normal file
7
tests/ref/box_sizing_sanity_check_ref.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div style="float: left; background: yellow;">Heeheehee</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue