mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
layout_2020: Implement align-content in flexbox
Align all flex lines per `align-content`.
This commit is contained in:
parent
03574d8191
commit
4a65dd0425
2 changed files with 36 additions and 10 deletions
|
@ -17,6 +17,7 @@ use crate::style_ext::ComputedValuesExt;
|
||||||
use crate::ContainingBlock;
|
use crate::ContainingBlock;
|
||||||
use atomic_refcell::AtomicRefMut;
|
use atomic_refcell::AtomicRefMut;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use style::properties::longhands::align_content::computed_value::T as AlignContent;
|
||||||
use style::properties::longhands::align_items::computed_value::T as AlignItems;
|
use style::properties::longhands::align_items::computed_value::T as AlignItems;
|
||||||
use style::properties::longhands::align_self::computed_value::T as AlignSelf;
|
use style::properties::longhands::align_self::computed_value::T as AlignSelf;
|
||||||
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
||||||
|
@ -46,6 +47,7 @@ struct FlexContext<'a> {
|
||||||
flex_axis: FlexAxis,
|
flex_axis: FlexAxis,
|
||||||
main_start_cross_start_sides_are: MainStartCrossStart,
|
main_start_cross_start_sides_are: MainStartCrossStart,
|
||||||
container_definite_inner_size: FlexRelativeVec2<Option<Length>>,
|
container_definite_inner_size: FlexRelativeVec2<Option<Length>>,
|
||||||
|
align_content: AlignContent,
|
||||||
align_items: AlignItems,
|
align_items: AlignItems,
|
||||||
justify_content: JustifyContent,
|
justify_content: JustifyContent,
|
||||||
}
|
}
|
||||||
|
@ -261,6 +263,7 @@ fn layout<'context, 'boxes>(
|
||||||
FlexWrap::Nowrap | FlexWrap::Wrap => false,
|
FlexWrap::Nowrap | FlexWrap::Wrap => false,
|
||||||
FlexWrap::WrapReverse => true,
|
FlexWrap::WrapReverse => true,
|
||||||
};
|
};
|
||||||
|
let align_content = containing_block.style.clone_align_content();
|
||||||
let align_items = containing_block.style.clone_align_items();
|
let align_items = containing_block.style.clone_align_items();
|
||||||
let justify_content = containing_block.style.clone_justify_content();
|
let justify_content = containing_block.style.clone_justify_content();
|
||||||
|
|
||||||
|
@ -272,6 +275,7 @@ fn layout<'context, 'boxes>(
|
||||||
container_max_cross_size,
|
container_max_cross_size,
|
||||||
container_is_single_line,
|
container_is_single_line,
|
||||||
flex_axis,
|
flex_axis,
|
||||||
|
align_content,
|
||||||
align_items,
|
align_items,
|
||||||
justify_content,
|
justify_content,
|
||||||
main_start_cross_start_sides_are: MainStartCrossStart::from(
|
main_start_cross_start_sides_are: MainStartCrossStart::from(
|
||||||
|
@ -315,30 +319,51 @@ fn layout<'context, 'boxes>(
|
||||||
|flex_context, mut line| line.layout(flex_context, container_main_size),
|
|flex_context, mut line| line.layout(flex_context, container_main_size),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let content_cross_size = flex_lines
|
||||||
|
.iter()
|
||||||
|
.map(|line| line.cross_size)
|
||||||
|
.sum::<Length>();
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-cross-container
|
// https://drafts.csswg.org/css-flexbox/#algo-cross-container
|
||||||
let container_cross_size = flex_context
|
let container_cross_size = flex_context
|
||||||
.container_definite_inner_size
|
.container_definite_inner_size
|
||||||
.cross
|
.cross
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or(content_cross_size)
|
||||||
flex_lines
|
|
||||||
.iter()
|
|
||||||
.map(|line| line.cross_size)
|
|
||||||
.sum::<Length>()
|
|
||||||
})
|
|
||||||
.clamp_between_extremums(
|
.clamp_between_extremums(
|
||||||
flex_context.container_min_cross_size,
|
flex_context.container_min_cross_size,
|
||||||
flex_context.container_max_cross_size,
|
flex_context.container_max_cross_size,
|
||||||
);
|
);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-line-align
|
// https://drafts.csswg.org/css-flexbox/#algo-line-align
|
||||||
|
// Align all flex lines per `align-content`.
|
||||||
|
let line_count = flex_lines.len();
|
||||||
let mut cross_start_position_cursor = Length::zero();
|
let mut cross_start_position_cursor = Length::zero();
|
||||||
|
|
||||||
|
let line_interval = match flex_context.container_definite_inner_size.cross {
|
||||||
|
Some(cross_size) if line_count >= 2 => {
|
||||||
|
let free_space = cross_size - content_cross_size;
|
||||||
|
|
||||||
|
cross_start_position_cursor = match flex_context.align_content {
|
||||||
|
AlignContent::Center => free_space / 2.0,
|
||||||
|
AlignContent::SpaceAround => free_space / (line_count * 2) as CSSFloat,
|
||||||
|
AlignContent::FlexEnd => free_space,
|
||||||
|
_ => Length::zero(),
|
||||||
|
};
|
||||||
|
|
||||||
|
match flex_context.align_content {
|
||||||
|
AlignContent::SpaceBetween => free_space / (line_count - 1) as CSSFloat,
|
||||||
|
AlignContent::SpaceAround => free_space / line_count as CSSFloat,
|
||||||
|
_ => Length::zero(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => Length::zero(),
|
||||||
|
};
|
||||||
|
|
||||||
let line_cross_start_positions = flex_lines
|
let line_cross_start_positions = flex_lines
|
||||||
.iter()
|
.iter()
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
// FIXME: “Align all flex lines per `align-content`.”
|
|
||||||
// For now we hard-code the behavior of `align-content: flex-start`.
|
|
||||||
let cross_start = cross_start_position_cursor;
|
let cross_start = cross_start_position_cursor;
|
||||||
let cross_end = cross_start + line.cross_size;
|
let cross_end = cross_start + line.cross_size + line_interval;
|
||||||
cross_start_position_cursor = cross_end;
|
cross_start_position_cursor = cross_end;
|
||||||
cross_start
|
cross_start
|
||||||
})
|
})
|
||||||
|
|
|
@ -134,7 +134,8 @@ ${helpers.single_keyword(
|
||||||
${helpers.single_keyword(
|
${helpers.single_keyword(
|
||||||
"align-content",
|
"align-content",
|
||||||
"stretch flex-start flex-end center space-between space-around",
|
"stretch flex-start flex-end center space-between space-around",
|
||||||
engines="servo-2013",
|
engines="servo-2013 servo-2020",
|
||||||
|
servo_2020_pref="layout.flexbox.enabled",
|
||||||
extra_prefixes="webkit",
|
extra_prefixes="webkit",
|
||||||
spec="https://drafts.csswg.org/css-align/#propdef-align-content",
|
spec="https://drafts.csswg.org/css-align/#propdef-align-content",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue