mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Auto merge of #29946 - Loirooriol:clearance-option, r=mrobinson
Layout 2020: implement clearance as Option<Length> Clearance was implemented as a Length, where zero meant no clearance. However, having a clearance of 0px should be different than having no clearance, since the former can still prevent margin collapse. This patch keeps the existing behavior, so it won't be possible to get a clearance of Some(Length::zero()), but it prepares the terrain for a follow-up to fix calculate_clearance to return the proper thing. <!-- Please describe your changes on the following line: --> --- <!-- 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 do not require tests because there should be no change in behavior <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
a07ff91cfb
6 changed files with 42 additions and 24 deletions
|
@ -855,7 +855,7 @@ impl FlexLine<'_> {
|
|||
flex_context.sides_to_flow_relative(item.padding),
|
||||
flex_context.sides_to_flow_relative(item.border),
|
||||
margin,
|
||||
Length::zero(),
|
||||
None,
|
||||
collapsed_margin,
|
||||
),
|
||||
item_result.positioning_context,
|
||||
|
|
|
@ -744,7 +744,7 @@ impl FloatBox {
|
|||
margin,
|
||||
// Clearance is handled internally by the float placement logic, so there's no need
|
||||
// to store it explicitly in the fragment.
|
||||
Length::zero(), // clearance
|
||||
None, // clearance
|
||||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
},
|
||||
|
@ -826,9 +826,9 @@ impl SequentialLayoutState {
|
|||
/// needs to have.
|
||||
///
|
||||
/// https://www.w3.org/TR/2011/REC-CSS2-20110607/visuren.html#flow-control
|
||||
pub(crate) fn calculate_clearance(&self, clear_side: ClearSide) -> Length {
|
||||
pub(crate) fn calculate_clearance(&self, clear_side: ClearSide) -> Option<Length> {
|
||||
if clear_side == ClearSide::None {
|
||||
return Length::zero();
|
||||
return None;
|
||||
}
|
||||
|
||||
let hypothetical_block_position = self.current_block_position_including_margins();
|
||||
|
@ -848,7 +848,10 @@ impl SequentialLayoutState {
|
|||
.max(self.floats.clear_right_position)
|
||||
.max(hypothetical_block_position),
|
||||
};
|
||||
clear_position - hypothetical_block_position
|
||||
if hypothetical_block_position >= clear_position {
|
||||
return None;
|
||||
}
|
||||
Some(clear_position - hypothetical_block_position)
|
||||
}
|
||||
|
||||
/// Adds a new adjoining margin.
|
||||
|
|
|
@ -554,7 +554,7 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> {
|
|||
self.padding.clone(),
|
||||
self.border.clone(),
|
||||
self.margin.clone(),
|
||||
Length::zero(),
|
||||
None,
|
||||
CollapsedBlockMargins::zero(),
|
||||
);
|
||||
let last_fragment = self.last_box_tree_fragment && !at_line_break;
|
||||
|
@ -619,7 +619,7 @@ fn layout_atomic(
|
|||
pbm.padding,
|
||||
pbm.border,
|
||||
margin,
|
||||
Length::zero(),
|
||||
None,
|
||||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
},
|
||||
|
@ -701,7 +701,7 @@ fn layout_atomic(
|
|||
pbm.padding,
|
||||
pbm.border,
|
||||
margin,
|
||||
Length::zero(),
|
||||
None,
|
||||
CollapsedBlockMargins::zero(),
|
||||
)
|
||||
},
|
||||
|
|
|
@ -183,7 +183,7 @@ impl BlockFormattingContext {
|
|||
// The content height of a BFC root should include any float participating in that BFC
|
||||
// (https://drafts.csswg.org/css2/#root-height), we implement this by imagining there is
|
||||
// an element with `clear: both` after the actual contents.
|
||||
let clearance = sequential_layout_state.map_or(Length::zero(), |sequential_layout_state| {
|
||||
let clearance = sequential_layout_state.and_then(|sequential_layout_state| {
|
||||
sequential_layout_state.calculate_clearance(ClearSide::Both)
|
||||
});
|
||||
|
||||
|
@ -191,7 +191,7 @@ impl BlockFormattingContext {
|
|||
fragments: flow_layout.fragments,
|
||||
content_block_size: flow_layout.content_block_size +
|
||||
flow_layout.collapsible_margins_in_children.end.solve() +
|
||||
clearance,
|
||||
clearance.unwrap_or_else(Length::zero),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -650,7 +650,7 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
pbm.border.block_end == Length::zero() &&
|
||||
block_size == LengthOrAuto::Auto;
|
||||
|
||||
let mut clearance = Length::zero();
|
||||
let mut clearance = None;
|
||||
let parent_containing_block_position_info;
|
||||
match sequential_layout_state {
|
||||
None => parent_containing_block_position_info = None,
|
||||
|
@ -667,7 +667,9 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
// NB: This will be a no-op if we're collapsing margins with our children since that
|
||||
// can only happen if we have no block-start padding and border.
|
||||
sequential_layout_state.advance_block_position(
|
||||
pbm.padding.block_start + pbm.border.block_start + clearance,
|
||||
pbm.padding.block_start +
|
||||
pbm.border.block_start +
|
||||
clearance.unwrap_or_else(Length::zero),
|
||||
);
|
||||
|
||||
// We are about to lay out children. Update the offset between the block formatting
|
||||
|
@ -776,7 +778,9 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
|
||||
let content_rect = Rect {
|
||||
start_corner: Vec2 {
|
||||
block: pbm.padding.block_start + pbm.border.block_start + clearance,
|
||||
block: pbm.padding.block_start +
|
||||
pbm.border.block_start +
|
||||
clearance.unwrap_or_else(Length::zero),
|
||||
inline: pbm.padding.inline_start + pbm.border.inline_start + margin.inline_start,
|
||||
},
|
||||
size: Vec2 {
|
||||
|
@ -821,20 +825,25 @@ fn layout_in_flow_replaced_block_level<'a>(
|
|||
};
|
||||
let fragments = replaced.make_fragments(style, size.clone());
|
||||
|
||||
let mut clearance = Length::zero();
|
||||
let mut clearance = None;
|
||||
if let Some(ref mut sequential_layout_state) = sequential_layout_state {
|
||||
sequential_layout_state.adjoin_assign(&CollapsedMargin::new(margin.block_start));
|
||||
sequential_layout_state.collapse_margins();
|
||||
clearance = sequential_layout_state.calculate_clearance(ClearSide::from_style(style));
|
||||
sequential_layout_state.advance_block_position(
|
||||
pbm.border.block_sum() + pbm.padding.block_sum() + size.block + clearance,
|
||||
pbm.border.block_sum() +
|
||||
pbm.padding.block_sum() +
|
||||
size.block +
|
||||
clearance.unwrap_or_else(Length::zero),
|
||||
);
|
||||
sequential_layout_state.adjoin_assign(&CollapsedMargin::new(margin.block_end));
|
||||
};
|
||||
|
||||
let content_rect = Rect {
|
||||
start_corner: Vec2 {
|
||||
block: pbm.padding.block_start + pbm.border.block_start + clearance,
|
||||
block: pbm.padding.block_start +
|
||||
pbm.border.block_start +
|
||||
clearance.unwrap_or_else(Length::zero),
|
||||
inline: pbm.padding.inline_start + pbm.border.inline_start + margin.inline_start,
|
||||
},
|
||||
size,
|
||||
|
@ -915,8 +924,7 @@ impl PlacementState {
|
|||
match fragment {
|
||||
Fragment::Box(fragment) => {
|
||||
let fragment_block_margins = &fragment.block_margins_collapsed_with_children;
|
||||
let fragment_block_size = fragment.clearance +
|
||||
fragment.padding.block_sum() +
|
||||
let mut fragment_block_size = fragment.padding.block_sum() +
|
||||
fragment.border.block_sum() +
|
||||
fragment.content_rect.size.block;
|
||||
// We use `last_in_flow_margin_collapses_with_parent_end_margin` to implement
|
||||
|
@ -924,7 +932,8 @@ impl PlacementState {
|
|||
// > If the top and bottom margins of an element with clearance are adjoining,
|
||||
// > its margins collapse with the adjoining margins of following siblings but that
|
||||
// > resulting margin does not collapse with the bottom margin of the parent block.
|
||||
if fragment.clearance != Length::zero() {
|
||||
if let Some(clearance) = fragment.clearance {
|
||||
fragment_block_size += clearance;
|
||||
// Margins can't be adjoining if they are separated by clearance.
|
||||
// Setting `next_in_flow_margin_collapses_with_parent_start_margin` to false
|
||||
// prevents collapsing with the start margin of the parent, and will set
|
||||
|
@ -957,7 +966,7 @@ impl PlacementState {
|
|||
if fragment_block_margins.collapsed_through {
|
||||
// `fragment_block_size` is typically zero when collapsing through,
|
||||
// but we still need to consider it in case there is clearance.
|
||||
self.current_block_direction_position += fragment.clearance;
|
||||
self.current_block_direction_position += fragment_block_size;
|
||||
self.current_margin
|
||||
.adjoin_assign(&fragment_block_margins.end);
|
||||
} else {
|
||||
|
|
|
@ -31,7 +31,13 @@ pub(crate) struct BoxFragment {
|
|||
pub border: Sides<Length>,
|
||||
pub margin: Sides<Length>,
|
||||
|
||||
pub clearance: Length,
|
||||
/// When the `clear` property is not set to `none`, it may introduce clearance.
|
||||
/// Clearance is some extra spacing that is added above the top margin,
|
||||
/// so that the element doesn't overlap earlier floats in the same BFC.
|
||||
/// The presence of clearance prevents the top margin from collapsing with
|
||||
/// earlier margins or with the bottom margin of the parent block.
|
||||
/// https://drafts.csswg.org/css2/#clearance
|
||||
pub clearance: Option<Length>,
|
||||
|
||||
pub block_margins_collapsed_with_children: CollapsedBlockMargins,
|
||||
|
||||
|
@ -51,7 +57,7 @@ impl BoxFragment {
|
|||
padding: Sides<Length>,
|
||||
border: Sides<Length>,
|
||||
margin: Sides<Length>,
|
||||
clearance: Length,
|
||||
clearance: Option<Length>,
|
||||
block_margins_collapsed_with_children: CollapsedBlockMargins,
|
||||
) -> BoxFragment {
|
||||
let position = style.get_box().position;
|
||||
|
@ -85,7 +91,7 @@ impl BoxFragment {
|
|||
padding: Sides<Length>,
|
||||
border: Sides<Length>,
|
||||
margin: Sides<Length>,
|
||||
clearance: Length,
|
||||
clearance: Option<Length>,
|
||||
block_margins_collapsed_with_children: CollapsedBlockMargins,
|
||||
overconstrained: PhysicalSize<bool>,
|
||||
) -> BoxFragment {
|
||||
|
|
|
@ -620,7 +620,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
pbm.padding,
|
||||
pbm.border,
|
||||
margin,
|
||||
Length::zero(),
|
||||
None,
|
||||
CollapsedBlockMargins::zero(),
|
||||
physical_overconstrained,
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue