diff options
-rw-r--r-- | components/layout_2020/flexbox/layout.rs | 63 | ||||
-rw-r--r-- | components/layout_2020/flexbox/mod.rs | 8 | ||||
-rw-r--r-- | tests/wpt/meta/MANIFEST.json | 13 | ||||
-rw-r--r-- | tests/wpt/tests/css/css-flexbox/flexbox-align-self-baseline-compatability.html | 36 |
4 files changed, 92 insertions, 28 deletions
diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index 28854ecc048..3374844a32c 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -19,7 +19,7 @@ use style::values::computed::length::Size; use style::values::computed::Length; use style::values::generics::flex::GenericFlexBasis as FlexBasis; use style::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrNormal}; -use style::values::specified::align::AlignFlags; +use style::values::specified::align::{AlignFlags, AxisDirection}; use style::Zero; use super::geom::{FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec2}; @@ -99,9 +99,9 @@ struct FlexItemLayoutResult { } impl FlexItemLayoutResult { - fn get_or_synthesize_baseline_with_block_size(&self, block_size: Au, item: &FlexItem) -> Au { + fn get_or_synthesize_baseline_with_cross_size(&self, cross_size: Au, item: &FlexItem) -> Au { self.baseline_relative_to_margin_box - .unwrap_or_else(|| item.synthesized_baseline_relative_to_margin_box(block_size)) + .unwrap_or_else(|| item.synthesized_baseline_relative_to_margin_box(cross_size)) } fn collect_fragment( @@ -731,6 +731,7 @@ impl FlexContainer { _ => Au::zero(), }; + let inline_axis_is_main_axis = self.config.flex_axis == FlexAxis::Row; let mut baseline_alignment_participating_baselines = Baselines::default(); let mut all_baselines = Baselines::default(); let flex_item_fragments: Vec<_> = initial_line_layouts @@ -786,20 +787,27 @@ impl FlexContainer { }, }; - let line_shared_alignment_baseline = final_line_layout - .shared_alignment_baseline - .map(|baseline| baseline + flow_relative_line_position.block); + if inline_axis_is_main_axis { + let line_shared_alignment_baseline = final_line_layout + .shared_alignment_baseline + .map(|baseline| baseline + flow_relative_line_position.block); + if index == 0 { + baseline_alignment_participating_baselines.first = + line_shared_alignment_baseline; + } + if index == num_lines - 1 { + baseline_alignment_participating_baselines.last = + line_shared_alignment_baseline; + } + } + let line_all_baselines = final_line_layout .all_baselines .offset(flow_relative_line_position.block); if index == 0 { - baseline_alignment_participating_baselines.first = - line_shared_alignment_baseline; all_baselines.first = line_all_baselines.first; } if index == num_lines - 1 { - baseline_alignment_participating_baselines.last = - line_shared_alignment_baseline; all_baselines.last = line_all_baselines.last; } @@ -1389,7 +1397,7 @@ impl InitialFlexLineLayout<'_> { item.align_self.0.value(), AlignFlags::BASELINE | AlignFlags::LAST_BASELINE ) { - let baseline = item_result.get_or_synthesize_baseline_with_block_size( + let baseline = item_result.get_or_synthesize_baseline_with_cross_size( item_result.hypothetical_cross_size, item, ); @@ -1475,9 +1483,8 @@ impl InitialFlexLineLayout<'_> { item.layout(*used_main_size, flex_context, Some(used_cross_size)); } - // TODO: This also needs to check whether we have a compatible writing mode. let baseline = item_layout_result - .get_or_synthesize_baseline_with_block_size(used_cross_size, item); + .get_or_synthesize_baseline_with_cross_size(used_cross_size, item); if matches!( item.align_self.0.value(), AlignFlags::BASELINE | AlignFlags::LAST_BASELINE @@ -1758,8 +1765,23 @@ impl FlexItem<'_> { containing_block, ); - let baselines_relative_to_margin_box = - self.layout_baselines_relative_to_margin_box(&content_box_baselines); + let item_writing_mode_is_orthogonal_to_container_writing_mode = + flex_context.config.writing_mode.is_horizontal() != + non_replaced.style.effective_writing_mode().is_horizontal(); + let has_compatible_baseline = match flex_context.config.flex_axis { + FlexAxis::Row => !item_writing_mode_is_orthogonal_to_container_writing_mode, + FlexAxis::Column => item_writing_mode_is_orthogonal_to_container_writing_mode, + }; + + let baselines_relative_to_margin_box = if has_compatible_baseline { + content_box_baselines.offset( + self.margin.cross_start.auto_is(Au::zero) + + self.padding.cross_start + + self.border.cross_start, + ) + } else { + Baselines::default() + }; let baseline_relative_to_margin_box = match self.align_self.0.value() { // ‘baseline’ computes to ‘first baseline’. @@ -1793,17 +1815,6 @@ impl FlexItem<'_> { } } - fn layout_baselines_relative_to_margin_box( - &self, - baselines_relative_to_content_box: &Baselines, - ) -> Baselines { - baselines_relative_to_content_box.offset( - self.margin.cross_start.auto_is(Au::zero) + - self.padding.cross_start + - self.border.cross_start, - ) - } - fn synthesized_baseline_relative_to_margin_box(&self, content_size: Au) -> Au { // If the item does not have a baseline in the necessary axis, // then one is synthesized from the flex item’s border box. diff --git a/components/layout_2020/flexbox/mod.rs b/components/layout_2020/flexbox/mod.rs index 592d6d5e442..d7005fa357b 100644 --- a/components/layout_2020/flexbox/mod.rs +++ b/components/layout_2020/flexbox/mod.rs @@ -2,20 +2,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use geom::{FlexAxis, MainStartCrossStart}; +use geom::{FlexAxis, FlexRelativeVec2, MainStartCrossStart}; use serde::Serialize; use servo_arc::Arc as ServoArc; +use style::logical_geometry::WritingMode; use style::properties::longhands::align_items::computed_value::T as AlignItems; 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::ComputedValues; use style::values::computed::{AlignContent, JustifyContent}; -use style::values::specified::align::AlignFlags; +use style::values::specified::align::{AlignFlags, AxisDirection}; use crate::cell::ArcRefCell; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragment_tree::BaseFragmentInfo; use crate::positioned::AbsolutelyPositionedBox; +use crate::style_ext::ComputedValuesExt; mod construct; mod geom; @@ -26,6 +28,7 @@ mod layout; #[derive(Clone, Debug, Serialize)] pub(crate) struct FlexContainerConfig { container_is_single_line: bool, + writing_mode: WritingMode, flex_axis: FlexAxis, flex_direction: FlexDirection, flex_direction_is_reversed: bool, @@ -66,6 +69,7 @@ impl FlexContainerConfig { FlexContainerConfig { container_is_single_line, + writing_mode: container_style.effective_writing_mode(), flex_axis, flex_direction, flex_direction_is_reversed, diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index cb73d4b1a64..8858f00ef47 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -169326,6 +169326,19 @@ {} ] ], + "flexbox-align-self-baseline-compatability.html": [ + "42270c1b364c14dc21ba0eb67294eb263a4732f1", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "flexbox-align-self-baseline-horiz-001a.xhtml": [ "0460f4162f5f424b4693c19cab688f5b5db16fa3", [ diff --git a/tests/wpt/tests/css/css-flexbox/flexbox-align-self-baseline-compatability.html b/tests/wpt/tests/css/css-flexbox/flexbox-align-self-baseline-compatability.html new file mode 100644 index 00000000000..42270c1b364 --- /dev/null +++ b/tests/wpt/tests/css/css-flexbox/flexbox-align-self-baseline-compatability.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> + <link rel="author" title="Martin Robinson" href="mailto:mrobinson@igalia.com"> + <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> + <link rel="match" href="/css/reference/ref-filled-green-100px-square.xht"/> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#flex-baselines"/> + <meta name="assert" content="Test checks that item baselines orthogonal to the flex container's main axis do not affect baseline alignment."> + + <style> + .flex { + display: flex; + background: red; + width: 100px; + flex-direction: column; + flex-wrap: wrap; + } + + .flex > div { + width: 100px; + height: 50px; + background: green; + color: transparent; + align-self: baseline; + } + </style> + + <p>Test passes if there is a filled green square and <strong>no red</strong>.</p> + + <div class="flex"> + <div>A</div> + <!--The baseline of this child is different from the first, but because it + is orthogonal to the main axis of the flexbox, it does not affect the + positioning of the item, even with `baseline` alignment --> + <div style="font-size: 200%">A</div> + </div> +</html> |