mirror of
https://github.com/servo/servo.git
synced 2025-09-23 13:20:11 +01:00
Auto merge of #29719 - stshine:flexbox-justify-content, r=Loirooriol
layout 2020: Implement justify-content in flexbox Align the items along the main-axis per justify-content. <!-- 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 - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- 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
03574d8191
24 changed files with 72 additions and 82 deletions
|
@ -22,9 +22,11 @@ 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;
|
||||||
use style::properties::longhands::flex_direction::computed_value::T as FlexDirection;
|
use style::properties::longhands::flex_direction::computed_value::T as FlexDirection;
|
||||||
use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
||||||
|
use style::properties::longhands::justify_content::computed_value::T as JustifyContent;
|
||||||
use style::values::computed::length::Size;
|
use style::values::computed::length::Size;
|
||||||
use style::values::computed::Length;
|
use style::values::computed::Length;
|
||||||
use style::values::generics::flex::GenericFlexBasis as FlexBasis;
|
use style::values::generics::flex::GenericFlexBasis as FlexBasis;
|
||||||
|
use style::values::CSSFloat;
|
||||||
use style::Zero;
|
use style::Zero;
|
||||||
|
|
||||||
// FIMXE: “Flex items […] `z-index` values other than `auto` create a stacking context
|
// FIMXE: “Flex items […] `z-index` values other than `auto` create a stacking context
|
||||||
|
@ -45,6 +47,7 @@ struct FlexContext<'a> {
|
||||||
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_items: AlignItems,
|
align_items: AlignItems,
|
||||||
|
justify_content: JustifyContent,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A flex item with some intermediate results
|
/// A flex item with some intermediate results
|
||||||
|
@ -259,6 +262,7 @@ fn layout<'context, 'boxes>(
|
||||||
FlexWrap::WrapReverse => true,
|
FlexWrap::WrapReverse => true,
|
||||||
};
|
};
|
||||||
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 mut flex_context = FlexContext {
|
let mut flex_context = FlexContext {
|
||||||
layout_context,
|
layout_context,
|
||||||
|
@ -269,6 +273,7 @@ fn layout<'context, 'boxes>(
|
||||||
container_is_single_line,
|
container_is_single_line,
|
||||||
flex_axis,
|
flex_axis,
|
||||||
align_items,
|
align_items,
|
||||||
|
justify_content,
|
||||||
main_start_cross_start_sides_are: MainStartCrossStart::from(
|
main_start_cross_start_sides_are: MainStartCrossStart::from(
|
||||||
flex_direction,
|
flex_direction,
|
||||||
flex_wrap_reverse,
|
flex_wrap_reverse,
|
||||||
|
@ -669,10 +674,37 @@ impl FlexLine<'_> {
|
||||||
|
|
||||||
// Distribute any remaining free space
|
// Distribute any remaining free space
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-main-align
|
// https://drafts.csswg.org/css-flexbox/#algo-main-align
|
||||||
let item_main_margins = self.resolve_auto_main_margins(remaining_free_space);
|
let (item_main_margins, free_space_distributed) =
|
||||||
|
self.resolve_auto_main_margins(remaining_free_space);
|
||||||
|
|
||||||
// FIXME: “Align the items along the main-axis per justify-content.”
|
// Align the items along the main-axis per justify-content.
|
||||||
// For now we hard-code `justify-content` to `flex-start`.
|
let item_count = self.items.len();
|
||||||
|
let main_start_position = if free_space_distributed {
|
||||||
|
Length::zero()
|
||||||
|
} else {
|
||||||
|
match flex_context.justify_content {
|
||||||
|
JustifyContent::FlexEnd => remaining_free_space,
|
||||||
|
JustifyContent::Center => remaining_free_space / 2.0,
|
||||||
|
JustifyContent::SpaceAround => remaining_free_space / (item_count * 2) as CSSFloat,
|
||||||
|
_ => Length::zero(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_main_interval = if free_space_distributed {
|
||||||
|
Length::zero()
|
||||||
|
} else {
|
||||||
|
match flex_context.justify_content {
|
||||||
|
JustifyContent::SpaceBetween => {
|
||||||
|
if item_count > 1 {
|
||||||
|
remaining_free_space / (item_count - 1) as CSSFloat
|
||||||
|
} else {
|
||||||
|
Length::zero()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
JustifyContent::SpaceAround => remaining_free_space / item_count as CSSFloat,
|
||||||
|
_ => Length::zero(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-cross-margins
|
// https://drafts.csswg.org/css-flexbox/#algo-cross-margins
|
||||||
let item_cross_margins = self.items.iter().zip(&item_used_cross_sizes).map(
|
let item_cross_margins = self.items.iter().zip(&item_used_cross_sizes).map(
|
||||||
|
@ -697,8 +729,12 @@ impl FlexLine<'_> {
|
||||||
)
|
)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-main-align
|
// https://drafts.csswg.org/css-flexbox/#algo-main-align
|
||||||
let items_content_main_start_positions =
|
let items_content_main_start_positions = self.align_along_main_axis(
|
||||||
self.align_along_main_axis(&item_used_main_sizes, &item_margins);
|
&item_used_main_sizes,
|
||||||
|
&item_margins,
|
||||||
|
main_start_position,
|
||||||
|
item_main_interval,
|
||||||
|
);
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-flexbox/#algo-cross-align
|
// https://drafts.csswg.org/css-flexbox/#algo-cross-align
|
||||||
let item_content_cross_start_posititons = self
|
let item_content_cross_start_posititons = self
|
||||||
|
@ -1029,11 +1065,12 @@ impl<'items> FlexLine<'items> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the main-start and main-end margin of each item in the line,
|
// Return the main-start and main-end margin of each item in the line,
|
||||||
// with `auto` values resolved.
|
// with `auto` values resolved,
|
||||||
|
// and return whether free space has been distributed.
|
||||||
fn resolve_auto_main_margins(
|
fn resolve_auto_main_margins(
|
||||||
&self,
|
&self,
|
||||||
remaining_free_space: Length,
|
remaining_free_space: Length,
|
||||||
) -> impl Iterator<Item = (Length, Length)> + '_ {
|
) -> (impl Iterator<Item = (Length, Length)> + '_, bool) {
|
||||||
let each_auto_margin = if remaining_free_space > Length::zero() {
|
let each_auto_margin = if remaining_free_space > Length::zero() {
|
||||||
let auto_margins_count = self
|
let auto_margins_count = self
|
||||||
.items
|
.items
|
||||||
|
@ -1050,12 +1087,15 @@ impl<'items> FlexLine<'items> {
|
||||||
} else {
|
} else {
|
||||||
Length::zero()
|
Length::zero()
|
||||||
};
|
};
|
||||||
self.items.iter().map(move |item| {
|
(
|
||||||
(
|
self.items.iter().map(move |item| {
|
||||||
item.margin.main_start.auto_is(|| each_auto_margin),
|
(
|
||||||
item.margin.main_end.auto_is(|| each_auto_margin),
|
item.margin.main_start.auto_is(|| each_auto_margin),
|
||||||
)
|
item.margin.main_end.auto_is(|| each_auto_margin),
|
||||||
})
|
)
|
||||||
|
}),
|
||||||
|
each_auto_margin > Length::zero(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the coordinate of the main-start side of the content area of each item
|
/// Return the coordinate of the main-start side of the content area of each item
|
||||||
|
@ -1063,11 +1103,11 @@ impl<'items> FlexLine<'items> {
|
||||||
&'a self,
|
&'a self,
|
||||||
item_used_main_sizes: &'a [Length],
|
item_used_main_sizes: &'a [Length],
|
||||||
item_margins: &'a [FlexRelativeSides<Length>],
|
item_margins: &'a [FlexRelativeSides<Length>],
|
||||||
|
main_start_position: Length,
|
||||||
|
item_main_interval: Length,
|
||||||
) -> impl Iterator<Item = Length> + 'a {
|
) -> impl Iterator<Item = Length> + 'a {
|
||||||
// “Align the items along the main-axis”
|
// “Align the items along the main-axis”
|
||||||
// FIXME: “per justify-content.”
|
let mut main_position_cursor = main_start_position;
|
||||||
// For now we hard-code the behavior for `justify-content: flex-start`.
|
|
||||||
let mut main_position_cursor = Length::zero();
|
|
||||||
self.items
|
self.items
|
||||||
.iter()
|
.iter()
|
||||||
.zip(item_used_main_sizes)
|
.zip(item_used_main_sizes)
|
||||||
|
@ -1079,7 +1119,8 @@ impl<'items> FlexLine<'items> {
|
||||||
main_position_cursor += main_content_size +
|
main_position_cursor += main_content_size +
|
||||||
item.padding.main_end +
|
item.padding.main_end +
|
||||||
item.border.main_end +
|
item.border.main_end +
|
||||||
margin.main_end;
|
margin.main_end +
|
||||||
|
item_main_interval;
|
||||||
content_main_start_position
|
content_main_start_position
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,12 +92,13 @@ ${helpers.single_keyword(
|
||||||
gecko_enum_prefix = "StyleFlexWrap",
|
gecko_enum_prefix = "StyleFlexWrap",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
% if engine == "servo-2013":
|
% if engine in ["servo-2013", "servo-2020"]:
|
||||||
// FIXME: Update Servo to support the same Syntax as Gecko.
|
// FIXME: Update Servo to support the same Syntax as Gecko.
|
||||||
${helpers.single_keyword(
|
${helpers.single_keyword(
|
||||||
"justify-content",
|
"justify-content",
|
||||||
"flex-start stretch flex-end center space-between space-around",
|
"flex-start stretch 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-justify-content",
|
spec="https://drafts.csswg.org/css-align/#propdef-justify-content",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
|
|
|
@ -25,12 +25,3 @@
|
||||||
|
|
||||||
[.flexbox 19]
|
[.flexbox 19]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.flexbox 22]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.flexbox 21]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.flexbox 20]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flex-minimum-height-flex-items-014.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox-items-as-stacking-contexts-003.html]
|
|
||||||
expected: FAIL
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[flexbox-root-node-001a.html]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[flexbox-root-node-001b.html]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox_columns-flexitems-2.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox_columns-flexitems.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,9 +0,0 @@
|
||||||
[flexbox_justifycontent-center-overflow.html]
|
|
||||||
[span 1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[span 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[span 3]
|
|
||||||
expected: FAIL
|
|
|
@ -5,23 +5,20 @@
|
||||||
[.container > div 2]
|
[.container > div 2]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.container > div 3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.container > div 4]
|
[.container > div 4]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.container > div 5]
|
[.container > div 5]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.container > div 6]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.container > div 7]
|
[.container > div 7]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[.container > div 9]
|
[.container > div 9]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[.container > div 10]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
[.container > div 12]
|
[.container > div 12]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[flexbox_justifycontent-spacebetween-negative.html]
|
||||||
|
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
||||||
[flexbox_order-abspos-space-around.html]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flexbox_computedstyle_justify-content-center.html]
|
|
||||||
[flexbox | computed style | justify-content: center]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flexbox_computedstyle_justify-content-flex-end.html]
|
|
||||||
[flexbox | computed style | justify-content: flex-end]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flexbox_computedstyle_justify-content-flex-start.html]
|
|
||||||
[flexbox | computed style | justify-content: flex-start]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flexbox_computedstyle_justify-content-space-around.html]
|
|
||||||
[flexbox | computed style | justify-content: space-around]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[flexbox_computedstyle_justify-content-space-between.html]
|
|
||||||
[flexbox | computed style | justify-content: space-between]
|
|
||||||
expected: FAIL
|
|
|
@ -14,8 +14,5 @@
|
||||||
[Property align-self has initial value auto]
|
[Property align-self has initial value auto]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Property justify-content does not inherit]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Property align-content does not inherit]
|
[Property align-content does not inherit]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[justify-content-001.htm]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[justify-content-003.htm]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[justify-content-004.htm]
|
|
||||||
expected: FAIL
|
|
|
@ -1,2 +0,0 @@
|
||||||
[justify-content-005.htm]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[offsetTopLeftInScrollableParent.html]
|
|
||||||
[Margins on child and parent, border on child and parent, padding on child and parent]
|
|
||||||
expected: FAIL
|
|
Loading…
Add table
Add a link
Reference in a new issue