From d169a82d2e146704db3d9eb2b5f9f49f9ef8b1da Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Mon, 9 Sep 2024 07:44:16 -0700 Subject: [PATCH] layout: Implement proper absolute child position for flexbox (#33346) This implements the requirements outlined in the [flexbox specification] about how to position absolute children of flex containers. We must establish a static position rectangle (to use if all insets are auto) and also align the child into that rectangle. [flebox specification]: https://drafts.csswg.org/css-flexbox/#abspos-items Signed-off-by: Martin Robinson Co-authored-by: Oriol Brufau --- components/layout_2020/flexbox/layout.rs | 182 +++--- components/layout_2020/flexbox/mod.rs | 4 +- components/layout_2020/flow/inline/line.rs | 40 +- components/layout_2020/flow/inline/mod.rs | 4 +- components/layout_2020/flow/mod.rs | 32 +- .../fragment_tree/hoisted_shared_fragment.rs | 62 +-- components/layout_2020/geom.rs | 1 + components/layout_2020/positioned.rs | 276 ++++++--- components/layout_2020/style_ext.rs | 22 +- components/layout_2020/table/layout.rs | 9 +- .../abspos/safe-align-self-htb.html.ini | 36 -- ...cpos-fallback-justify-content-001.html.ini | 2 - .../abspos/position-absolute-001.html.ini | 78 +-- .../abspos/position-absolute-002.html.ini | 6 - .../abspos/position-absolute-012.html.ini | 116 ++-- .../abspos/position-absolute-013.html.ini | 522 +++++++----------- .../abspos/position-absolute-015.html.ini | 4 - ...ion-absolute-containing-block-001.html.ini | 2 - .../position-absolute-center-003.html.ini | 2 - .../position-absolute-center-004.html.ini | 2 - 20 files changed, 678 insertions(+), 724 deletions(-) delete mode 100644 tests/wpt/meta/css/css-align/abspos/safe-align-self-htb.html.ini delete mode 100644 tests/wpt/meta/css/css-flexbox/abspos/flex-abspos-staticpos-fallback-justify-content-001.html.ini delete mode 100644 tests/wpt/meta/css/css-flexbox/abspos/position-absolute-015.html.ini delete mode 100644 tests/wpt/meta/css/css-flexbox/abspos/position-absolute-containing-block-001.html.ini delete mode 100644 tests/wpt/meta/css/css-position/position-absolute-center-003.html.ini delete mode 100644 tests/wpt/meta/css/css-position/position-absolute-center-004.html.ini diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index a1feb4f711c..49c110df443 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -11,7 +11,6 @@ use itertools::izip; use style::computed_values::position::T as Position; use style::logical_geometry::Direction; 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::box_sizing::computed_value::T as BoxSizing; use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap; use style::properties::ComputedValues; @@ -136,7 +135,7 @@ impl FlexItemLayoutResult { final_line_cross_size, self.baseline_relative_to_margin_box.unwrap_or_default(), shared_alignment_baseline.unwrap_or_default(), - flex_context.config.flex_wrap_reverse, + flex_context.config.flex_wrap_is_reversed, ); let start_corner = FlexRelativeVec2 { @@ -244,16 +243,6 @@ struct FinalFlexLineLayout { } impl FlexContainerConfig { - fn align_for(&self, align_self: AlignSelf) -> AlignItems { - let value = align_self.0 .0.value(); - let mapped_value = match value { - AlignFlags::AUTO => self.align_items.0, - AlignFlags::NORMAL => AlignFlags::STRETCH, - _ => value, - }; - AlignItems(mapped_value) - } - /// Whether an item with an `auto` preferred cross size needs to be stretched /// to fill the flex container. /// @@ -264,10 +253,40 @@ impl FlexContainerConfig { ) -> bool { self.container_is_single_line && item_with_auto_cross_size_stretches_to_line_size( - self.align_for(item_style.clone_align_self()), + AlignItems(self.resolve_align_self_for_child(item_style)), item_margin, ) } + + fn resolve_reversable_flex_alignment( + &self, + align_flags: AlignFlags, + reversed: bool, + ) -> AlignFlags { + match (align_flags.value(), reversed) { + (AlignFlags::FLEX_START, false) => AlignFlags::START | align_flags.flags(), + (AlignFlags::FLEX_START, true) => AlignFlags::END | align_flags.flags(), + (AlignFlags::FLEX_END, false) => AlignFlags::END | align_flags.flags(), + (AlignFlags::FLEX_END, true) => AlignFlags::START | align_flags.flags(), + (_, _) => align_flags, + } + } + + fn resolve_align_self_for_child(&self, child_style: &ComputedValues) -> AlignFlags { + self.resolve_reversable_flex_alignment( + child_style + .resolve_align_self(self.align_items, AlignItems(AlignFlags::STRETCH)) + .0, + self.flex_wrap_is_reversed, + ) + } + + fn resolve_justify_content_for_child(&self) -> AlignFlags { + self.resolve_reversable_flex_alignment( + self.justify_content.0.primary(), + self.flex_direction_is_reversed, + ) + } } impl FlexContext<'_> { @@ -299,10 +318,6 @@ impl FlexContext<'_> { rect, ) } - - fn align_for(&self, align_self: AlignSelf) -> AlignItems { - self.config.align_for(align_self) - } } #[derive(Debug, Default)] @@ -632,24 +647,15 @@ impl FlexContainer { flex_context.container_max_cross_size, ); - let content_block_size = match flex_context.config.flex_axis { - FlexAxis::Row => { - // `container_main_size` ends up unused here but in this case that’s fine - // since it was already exactly the one decided by the outer formatting context. - container_cross_size - }, - FlexAxis::Column => { - // FIXME: `container_cross_size` ends up unused here, which is a bug. - // It is meant to be the used inline-size, but the parent formatting context - // has already decided a possibly-different used inline-size. - // The spec is missing something to resolve this conflict: - // https://github.com/w3c/csswg-drafts/issues/5190 - // And we’ll need to change the signature of `IndependentFormattingContext::layout` - // to allow the inner formatting context to “negotiate” a used inline-size - // with the outer one somehow. - container_main_size - }, + let container_size = FlexRelativeVec2 { + main: container_main_size, + cross: container_cross_size, }; + let content_block_size = flex_context + .config + .flex_axis + .vec2_to_flow_relative(container_size) + .block; let mut remaining_free_cross_space = flex_context .container_definite_inner_size @@ -704,23 +710,13 @@ impl FlexContainer { }; // Implement "unsafe" alignment. "safe" alignment is handled by the fallback process above. + let resolved_align_content = self.config.resolve_reversable_flex_alignment( + resolved_align_content, + flex_context.config.flex_wrap_is_reversed, + ); let mut cross_start_position_cursor = match resolved_align_content { AlignFlags::START => Au::zero(), - AlignFlags::FLEX_START => { - if flex_context.config.flex_wrap_reverse { - remaining_free_cross_space - } else { - Au::zero() - } - }, AlignFlags::END => remaining_free_cross_space, - AlignFlags::FLEX_END => { - if flex_context.config.flex_wrap_reverse { - Au::zero() - } else { - remaining_free_cross_space - } - }, AlignFlags::CENTER => remaining_free_cross_space / 2, AlignFlags::STRETCH => Au::zero(), AlignFlags::SPACE_BETWEEN => Au::zero(), @@ -764,7 +760,7 @@ impl FlexContainer { cross_gap; let flow_relative_line_position = - match (self.config.flex_axis, self.config.flex_wrap_reverse) { + match (self.config.flex_axis, self.config.flex_wrap_is_reversed) { (FlexAxis::Row, false) => LogicalVec2 { block: line_cross_start_position, inline: Au::zero(), @@ -824,16 +820,13 @@ impl FlexContainer { let fragments = absolutely_positioned_items_with_original_order .into_iter() .map(|child_as_abspos| match child_as_abspos { - FlexContent::AbsolutelyPositionedBox(absolutely_positioned) => { - let hoisted_box = AbsolutelyPositionedBox::to_hoisted( - absolutely_positioned, - LogicalVec2::zero(), + FlexContent::AbsolutelyPositionedBox(absolutely_positioned_box) => self + .create_absolutely_positioned_flex_child_fragment( + absolutely_positioned_box, containing_block, - ); - let hoisted_fragment = hoisted_box.fragment.clone(); - positioning_context.push(hoisted_box); - Fragment::AbsoluteOrFixedPositioned(hoisted_fragment) - }, + container_size, + positioning_context, + ), FlexContent::FlexItemPlaceholder => { // The `flex_item_fragments` iterator yields one fragment // per flex item, in the original order. @@ -842,7 +835,6 @@ impl FlexContainer { let fragment = Fragment::Box(fragment); child_positioning_context.adjust_static_position_of_hoisted_fragments( &fragment, - self.style.effective_writing_mode(), PositioningContextLength::zero(), ); positioning_context.append(child_positioning_context); @@ -871,6 +863,68 @@ impl FlexContainer { } } + /// Create a absolutely positioned flex child fragment, using the rules the + /// specification dictates. This should take into account the alignment and + /// justification values of the container and the child to position it within a + /// "inset-modified containing block," which may be either the "static-position + /// rectangle" that's calculated below or a modified version of the absolute's + /// containing block adjusted by the insets specified in the item's style. + /// + /// From : + /// > The cross-axis edges of the static-position rectangle of an + /// > absolutely-positioned child of a flex container are the content edges of the + /// > flex container The main-axis edges of the static-position rectangle are where + /// > the margin edges of the child would be positioned if it were the sole flex item + /// > in the flex container, assuming both the child and the flex container were + /// > fixed-size boxes of their used size. (For this purpose, auto margins are + /// > treated as zero.) + fn create_absolutely_positioned_flex_child_fragment( + &self, + absolutely_positioned_box: ArcRefCell, + containing_block: &ContainingBlock, + container_size: FlexRelativeVec2, + positioning_context: &mut PositioningContext, + ) -> Fragment { + let alignment = { + let fragment = absolutely_positioned_box.borrow(); + let make_flex_only_values_directional_for_absolutes = + |value: AlignFlags, reversed: bool| match (value.value(), reversed) { + (AlignFlags::NORMAL | AlignFlags::AUTO | AlignFlags::STRETCH, true) => { + AlignFlags::END | AlignFlags::SAFE + }, + (AlignFlags::STRETCH, false) => AlignFlags::START | AlignFlags::SAFE, + _ => value, + }; + let cross = make_flex_only_values_directional_for_absolutes( + self.config + .resolve_align_self_for_child(fragment.context.style()), + self.config.flex_wrap_is_reversed, + ); + let main = make_flex_only_values_directional_for_absolutes( + self.config.resolve_justify_content_for_child(), + self.config.flex_direction_is_reversed, + ); + + FlexRelativeVec2 { cross, main } + }; + let logical_alignment = self.config.flex_axis.vec2_to_flow_relative(alignment); + + let static_position_rect = LogicalRect { + start_corner: LogicalVec2::zero(), + size: self.config.flex_axis.vec2_to_flow_relative(container_size), + } + .to_physical(containing_block.effective_writing_mode()); + + let hoisted_box = AbsolutelyPositionedBox::to_hoisted( + absolutely_positioned_box, + static_position_rect, + logical_alignment, + ); + let hoisted_fragment = hoisted_box.fragment.clone(); + positioning_context.push(hoisted_box); + Fragment::AbsoluteOrFixedPositioned(hoisted_fragment) + } + fn available_cross_space_for_flex_items( &self, containing_block_for_container: &ContainingBlock, @@ -1022,8 +1076,11 @@ impl<'a> FlexItem<'a> { cross: flex_relative_content_min_size.cross.auto_is(Au::zero), }; - let align_self = flex_context.align_for(box_.style().clone_align_self()); - + let align_self = AlignItems( + flex_context + .config + .resolve_align_self_for_child(box_.style()), + ); let (flex_base_size, flex_base_size_is_definite) = box_.flex_base_size( flex_context.layout_context, &containing_block.into(), @@ -1922,8 +1979,7 @@ impl FlexItem<'_> { Au::zero() } else { match self.align_self.0.value() { - AlignFlags::FLEX_START | AlignFlags::STRETCH => Au::zero(), - AlignFlags::FLEX_END => ending_alignment, + AlignFlags::STRETCH => Au::zero(), AlignFlags::CENTER => ending_alignment / 2, AlignFlags::BASELINE | AlignFlags::LAST_BASELINE => { max_propagated_baseline - propagated_baseline diff --git a/components/layout_2020/flexbox/mod.rs b/components/layout_2020/flexbox/mod.rs index e6aa46c8104..b78be05cd8f 100644 --- a/components/layout_2020/flexbox/mod.rs +++ b/components/layout_2020/flexbox/mod.rs @@ -33,7 +33,7 @@ pub(crate) struct FlexContainerConfig { flex_direction: FlexDirection, flex_direction_is_reversed: bool, flex_wrap: FlexWrap, - flex_wrap_reverse: bool, + flex_wrap_is_reversed: bool, main_start_cross_start_sides_are: MainStartCrossStart, align_content: AlignContent, align_items: AlignItems, @@ -74,7 +74,7 @@ impl FlexContainerConfig { flex_direction, flex_direction_is_reversed, flex_wrap, - flex_wrap_reverse, + flex_wrap_is_reversed: flex_wrap_reverse, main_start_cross_start_sides_are, align_content, align_items, diff --git a/components/layout_2020/flow/inline/line.rs b/components/layout_2020/flow/inline/line.rs index 468d8fda825..f89c2e32dfa 100644 --- a/components/layout_2020/flow/inline/line.rs +++ b/components/layout_2020/flow/inline/line.rs @@ -11,6 +11,7 @@ use style::properties::ComputedValues; use style::values::computed::Length; use style::values::generics::box_::{GenericVerticalAlign, VerticalAlignKeyword}; use style::values::generics::font::LineHeight; +use style::values::specified::align::AlignFlags; use style::values::specified::box_::DisplayOutside; use style::values::specified::text::TextDecorationLine; use style::values::Either; @@ -24,7 +25,7 @@ use crate::cell::ArcRefCell; use crate::fragment_tree::{ BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, Fragment, TextFragment, }; -use crate::geom::{LogicalRect, LogicalVec2, ToLogical}; +use crate::geom::{LogicalRect, LogicalVec2}; use crate::positioned::{ relative_adjustement, AbsolutelyPositionedBox, PositioningContext, PositioningContextLength, }; @@ -368,15 +369,13 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { }; let ifc_writing_mode = self.layout.containing_block.effective_writing_mode(); - if inner_state - .flags - .contains(LineLayoutInlineContainerFlags::HAD_ANY_FLOATS) - { - for fragment in inner_state.fragments.iter_mut() { - if let Fragment::Float(box_fragment) = fragment { + for fragment in inner_state.fragments.iter_mut() { + match fragment { + Fragment::Float(box_fragment) => { box_fragment.content_rect.origin -= pbm_sums.start_offset().to_physical_size(ifc_writing_mode); - } + }, + _ => {}, } } @@ -404,7 +403,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { positioning_context .layout_collected_children(self.layout.layout_context, &mut fragment); positioning_context.adjust_static_position_of_hoisted_fragments_with_offset( - &fragment.content_rect.origin.to_logical(ifc_writing_mode), + &fragment.content_rect.origin.to_vector(), PositioningContextLength::zero(), ); self.current_positioning_context_mut() @@ -413,7 +412,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { Either::Second(start_offset) => { self.current_positioning_context_mut() .adjust_static_position_of_hoisted_fragments_with_offset( - &fragment.content_rect.origin.to_logical(ifc_writing_mode), + &fragment.content_rect.origin.to_vector(), start_offset, ); }, @@ -526,11 +525,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { if let Some(mut positioning_context) = atomic.positioning_context { positioning_context.adjust_static_position_of_hoisted_fragments_with_offset( - &atomic - .fragment - .content_rect - .origin - .to_logical(ifc_writing_mode), + &atomic.fragment.content_rect.origin.to_vector(), PositioningContextLength::zero(), ); self.current_positioning_context_mut() @@ -574,10 +569,21 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { } }; + // Since alignment of absolutes in inlines is currently always `start`, the size of + // of the static position rectangle does not matter. + let static_position_rect = LogicalRect { + start_corner: initial_start_corner, + size: LogicalVec2::zero(), + } + .to_physical(self.layout.containing_block.effective_writing_mode()); + let hoisted_box = AbsolutelyPositionedBox::to_hoisted( absolute.absolutely_positioned_box.clone(), - initial_start_corner.into(), - self.layout.containing_block, + static_position_rect, + LogicalVec2 { + inline: AlignFlags::START, + block: AlignFlags::START, + }, ); let hoisted_fragment = hoisted_box.fragment.clone(); self.current_positioning_context_mut().push(hoisted_box); diff --git a/components/layout_2020/flow/inline/mod.rs b/components/layout_2020/flow/inline/mod.rs index fa0d28e8c8e..44a284cdf89 100644 --- a/components/layout_2020/flow/inline/mod.rs +++ b/components/layout_2020/flow/inline/mod.rs @@ -886,13 +886,13 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { }, }; + let line_rect = line_rect.to_physical(self.containing_block.effective_writing_mode()); self.positioning_context .adjust_static_position_of_hoisted_fragments_with_offset( - &line_rect.start_corner, + &line_rect.origin.to_vector(), start_positioning_context_length, ); - let line_rect = line_rect.to_physical(self.containing_block.effective_writing_mode()); self.fragments .push(Fragment::Positioning(PositioningFragment::new_anonymous( line_rect, fragments, diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 3f3f7334182..07ee8ba0307 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -15,6 +15,7 @@ use style::computed_values::float::T as Float; use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::computed::{Length, LengthOrAuto, Size}; +use style::values::specified::align::AlignFlags; use style::values::specified::{Display, TextAlignKeyword}; use style::Zero; @@ -594,7 +595,6 @@ fn layout_block_level_children_in_parallel( placement_state.place_fragment_and_update_baseline(&mut fragment, None); child_positioning_context.adjust_static_position_of_hoisted_fragments( &fragment, - containing_block.effective_writing_mode(), PositioningContextLength::zero(), ); positioning_context.append(child_positioning_context); @@ -632,7 +632,6 @@ fn layout_block_level_children_sequentially( .place_fragment_and_update_baseline(&mut fragment, Some(sequential_layout_state)); positioning_context.adjust_static_position_of_hoisted_fragments( &fragment, - containing_block.effective_writing_mode(), positioning_context_length_before_layout, ); @@ -709,11 +708,14 @@ impl BlockLevelBox { BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { let hoisted_box = AbsolutelyPositionedBox::to_hoisted( box_.clone(), - // This is incorrect, however we do not know the - // correct positioning until later, in place_block_level_fragment, - // and this value will be adjusted there - LogicalVec2::zero(), - containing_block, + // This is incorrect, however we do not know the correct positioning + // until later, in PlacementState::place_fragment, and this value will be + // adjusted there + PhysicalRect::zero(), + LogicalVec2 { + inline: AlignFlags::START, + block: AlignFlags::START, + }, ); let hoisted_fragment = hoisted_box.fragment.clone(); positioning_context.push(hoisted_box); @@ -1817,11 +1819,17 @@ impl PlacementState { } }, Fragment::AbsoluteOrFixedPositioned(fragment) => { - let offset = LogicalVec2 { - block: (self.current_margin.solve() + self.current_block_direction_position), - inline: Au::zero(), - }; - fragment.borrow_mut().adjust_offsets(offset); + // The alignment of absolutes in block flow layout is always "start", so the size of + // the static position rectangle does not matter. + fragment.borrow_mut().static_position_rect = LogicalRect { + start_corner: LogicalVec2 { + block: (self.current_margin.solve() + + self.current_block_direction_position), + inline: Au::zero(), + }, + size: LogicalVec2::zero(), + } + .to_physical(self.writing_mode); }, Fragment::Float(box_fragment) => { let sequential_layout_state = sequential_layout_state diff --git a/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs b/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs index ed2a9b253dc..71c1f9d37c9 100644 --- a/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs +++ b/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs @@ -4,11 +4,11 @@ use app_units::Au; use serde::Serialize; -use style::values::computed::LengthPercentage; +use style::values::specified::align::AlignFlags; use super::Fragment; use crate::cell::ArcRefCell; -use crate::geom::LogicalVec2; +use crate::geom::{LogicalVec2, PhysicalRect, PhysicalVec}; /// A reference to a Fragment which is shared between `HoistedAbsolutelyPositionedBox` /// and its placeholder `AbsoluteOrFixedPositionedFragment` in the original tree position. @@ -16,53 +16,35 @@ use crate::geom::LogicalVec2; #[derive(Serialize)] pub(crate) struct HoistedSharedFragment { pub fragment: Option>, - pub box_offsets: LogicalVec2, + /// The "static-position rect" of this absolutely positioned box. This is defined by the + /// layout mode from which the box originates. + /// + /// See + pub static_position_rect: PhysicalRect, + /// The resolved alignment values used for aligning this absolutely positioned element + /// if the "static-position rect" ends up being the "inset-modified containing block". + /// These values are dependent on the layout mode (currently only interesting for + /// flexbox). + pub resolved_alignment: LogicalVec2, } impl HoistedSharedFragment { - pub(crate) fn new(box_offsets: LogicalVec2) -> Self { + pub(crate) fn new( + static_position_rect: PhysicalRect, + resolved_alignment: LogicalVec2, + ) -> Self { HoistedSharedFragment { fragment: None, - box_offsets, + static_position_rect, + resolved_alignment, } } } impl HoistedSharedFragment { - /// In some cases `inset: auto`-positioned elements do not know their precise - /// position until after they're hoisted. This lets us adjust auto values - /// after the fact. - pub(crate) fn adjust_offsets(&mut self, offsets: LogicalVec2) { - self.box_offsets.inline.adjust_offset(offsets.inline); - self.box_offsets.block.adjust_offset(offsets.block); - } -} - -#[derive(Clone, Debug, Serialize)] -pub(crate) enum AbsoluteBoxOffsets { - StaticStart { - start: Au, - }, - Start { - start: LengthPercentage, - }, - End { - end: LengthPercentage, - }, - Both { - start: LengthPercentage, - end: LengthPercentage, - }, -} - -impl AbsoluteBoxOffsets { - pub(crate) fn both_specified(&self) -> bool { - matches!(self, AbsoluteBoxOffsets::Both { .. }) - } - - pub(crate) fn adjust_offset(&mut self, new_offset: Au) { - if let AbsoluteBoxOffsets::StaticStart { ref mut start } = *self { - *start = new_offset - } + /// `inset: auto`-positioned elements do not know their precise position until after + /// they're hoisted. This lets us adjust auto values after the fact. + pub(crate) fn adjust_offsets(&mut self, offset: &PhysicalVec) { + self.static_position_rect = self.static_position_rect.translate(*offset); } } diff --git a/components/layout_2020/geom.rs b/components/layout_2020/geom.rs index adb60830019..965d096223b 100644 --- a/components/layout_2020/geom.rs +++ b/components/layout_2020/geom.rs @@ -18,6 +18,7 @@ use crate::ContainingBlock; pub type PhysicalPoint = euclid::Point2D; pub type PhysicalSize = euclid::Size2D; +pub type PhysicalVec = euclid::Vector2D; pub type PhysicalRect = euclid::Rect; pub type PhysicalSides = euclid::SideOffsets2D; pub type AuOrAuto = AutoOr; diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 10f86fea676..cca0a778fe4 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -7,9 +7,8 @@ use rayon::iter::IntoParallelRefMutIterator; use rayon::prelude::{IndexedParallelIterator, ParallelIterator}; use serde::Serialize; use style::computed_values::position::T as Position; -use style::logical_geometry::WritingMode; use style::properties::ComputedValues; -use style::values::computed::Length; +use style::values::specified::align::{AlignFlags, AxisDirection}; use style::values::specified::text::TextDecorationLine; use style::Zero; @@ -19,12 +18,11 @@ use crate::dom::NodeExt; use crate::dom_traversal::{Contents, NodeAndStyleInfo}; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragment_tree::{ - AbsoluteBoxOffsets, BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, - HoistedSharedFragment, + BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, HoistedSharedFragment, }; use crate::geom::{ AuOrAuto, LengthOrAuto, LengthPercentageOrAuto, LogicalRect, LogicalSides, LogicalVec2, - PhysicalPoint, PhysicalRect, ToLogical, + PhysicalPoint, PhysicalRect, PhysicalVec, ToLogical, }; use crate::style_ext::{ComputedValuesExt, DisplayInside}; use crate::{ContainingBlock, DefiniteContainingBlock, IndefiniteContainingBlock}; @@ -72,49 +70,16 @@ impl AbsolutelyPositionedBox { } pub(crate) fn to_hoisted( - self_: ArcRefCell, - initial_start_corner: LogicalVec2, - containing_block: &ContainingBlock, + absolutely_positioned_box: ArcRefCell, + static_position_rectangle: PhysicalRect, + resolved_alignment: LogicalVec2, ) -> HoistedAbsolutelyPositionedBox { - fn absolute_box_offsets( - initial_static_start: Length, - start: LengthPercentageOrAuto<'_>, - end: LengthPercentageOrAuto<'_>, - ) -> AbsoluteBoxOffsets { - match (start.non_auto(), end.non_auto()) { - (None, None) => AbsoluteBoxOffsets::StaticStart { - start: initial_static_start.into(), - }, - (Some(start), Some(end)) => AbsoluteBoxOffsets::Both { - start: start.clone(), - end: end.clone(), - }, - (None, Some(end)) => AbsoluteBoxOffsets::End { end: end.clone() }, - (Some(start), None) => AbsoluteBoxOffsets::Start { - start: start.clone(), - }, - } - } - - let box_offsets = { - let box_ = self_.borrow(); - let box_offsets = box_.context.style().box_offsets(containing_block); - LogicalVec2 { - inline: absolute_box_offsets( - initial_start_corner.inline, - box_offsets.inline_start, - box_offsets.inline_end, - ), - block: absolute_box_offsets( - initial_start_corner.block, - box_offsets.block_start, - box_offsets.block_end, - ), - } - }; HoistedAbsolutelyPositionedBox { - fragment: ArcRefCell::new(HoistedSharedFragment::new(box_offsets)), - absolutely_positioned_box: self_, + fragment: ArcRefCell::new(HoistedSharedFragment::new( + static_position_rectangle, + resolved_alignment, + )), + absolutely_positioned_box, } } } @@ -178,7 +143,6 @@ impl PositioningContext { pub(crate) fn adjust_static_position_of_hoisted_fragments( &mut self, parent_fragment: &Fragment, - parent_fragment_writing_mode: WritingMode, index: PositioningContextLength, ) { let start_offset = match &parent_fragment { @@ -186,37 +150,39 @@ impl PositioningContext { Fragment::AbsoluteOrFixedPositioned(_) => return, Fragment::Positioning(fragment) => &fragment.rect.origin, _ => unreachable!(), - } - .to_logical(parent_fragment_writing_mode); - self.adjust_static_position_of_hoisted_fragments_with_offset(&start_offset, index); + }; + self.adjust_static_position_of_hoisted_fragments_with_offset( + &start_offset.to_vector(), + index, + ); } /// See documentation for [PositioningContext::adjust_static_position_of_hoisted_fragments]. pub(crate) fn adjust_static_position_of_hoisted_fragments_with_offset( &mut self, - start_offset: &LogicalVec2, + offset: &PhysicalVec, index: PositioningContextLength, ) { - let update_fragment_if_needed = |hoisted_fragment: &mut HoistedAbsolutelyPositionedBox| { - let mut fragment = hoisted_fragment.fragment.borrow_mut(); - if let AbsoluteBoxOffsets::StaticStart { start } = &mut fragment.box_offsets.inline { - *start += start_offset.inline; - } - if let AbsoluteBoxOffsets::StaticStart { start } = &mut fragment.box_offsets.block { - *start += start_offset.block; - } - }; - if let Some(hoisted_boxes) = self.for_nearest_positioned_ancestor.as_mut() { hoisted_boxes .iter_mut() .skip(index.for_nearest_positioned_ancestor) - .for_each(update_fragment_if_needed); + .for_each(|hoisted_fragment| { + hoisted_fragment + .fragment + .borrow_mut() + .adjust_offsets(offset) + }) } self.for_nearest_containing_block_for_all_descendants .iter_mut() .skip(index.for_nearest_containing_block_for_all_descendants) - .for_each(update_fragment_if_needed); + .for_each(|hoisted_fragment| { + hoisted_fragment + .fragment + .borrow_mut() + .adjust_offsets(offset) + }) } /// Given `fragment_layout_fn`, a closure which lays out a fragment in a provided @@ -486,11 +452,9 @@ impl HoistedAbsolutelyPositionedBox { let cbis = containing_block.size.inline; let cbbs = containing_block.size.block; let mut absolutely_positioned_box = self.absolutely_positioned_box.borrow_mut(); - let containing_block_writing_mode = containing_block.effective_writing_mode(); - let pbm = absolutely_positioned_box - .context - .style() - .padding_border_margin(&containing_block.into()); + let containing_block_writing_mode = containing_block.style.effective_writing_mode(); + let style = absolutely_positioned_box.context.style().clone(); + let pbm = style.padding_border_margin(&containing_block.into()); let computed_size = match &absolutely_positioned_box.context { IndependentFormattingContext::Replaced(replaced) => { @@ -506,28 +470,62 @@ impl HoistedAbsolutelyPositionedBox { block: LengthOrAuto::LengthPercentage(used_size.block.into()), } }, - IndependentFormattingContext::NonReplaced(non_replaced) => non_replaced - .style - .content_box_size(&containing_block.into(), &pbm), + IndependentFormattingContext::NonReplaced(..) => { + style.content_box_size(&containing_block.into(), &pbm) + }, }; let shared_fragment = self.fragment.borrow(); + let static_position_rect = shared_fragment + .static_position_rect + .to_logical(containing_block_writing_mode); + + let indefinite_containing_block = containing_block.into(); + let box_offset = style.box_offsets(&indefinite_containing_block); + + // When the "static-position rect" doesn't come into play, we do not do any alignment + // in the inline axis. + let inline_box_offsets = AbsoluteBoxOffsets { + start: box_offset.inline_start, + end: box_offset.inline_end, + }; + let inline_alignment = match inline_box_offsets.either_specified() { + true => AlignFlags::START | AlignFlags::SAFE, + false => shared_fragment.resolved_alignment.inline, + }; + let inline_axis_solver = AbsoluteAxisSolver { + axis: AxisDirection::Inline, containing_size: cbis, padding_border_sum: pbm.padding_border_sums.inline, computed_margin_start: pbm.margin.inline_start, computed_margin_end: pbm.margin.inline_end, avoid_negative_margin_start: true, - box_offsets: &shared_fragment.box_offsets.inline, + box_offsets: inline_box_offsets, + static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Inline), + alignment: inline_alignment, }; + // When the "static-position rect" doesn't come into play, we re-resolve "align-self" + // against this containing block. + let block_box_offsets = AbsoluteBoxOffsets { + start: box_offset.block_start, + end: box_offset.block_end, + }; + let block_alignment = match block_box_offsets.either_specified() { + true => style.clone_align_self().0 .0, + false => shared_fragment.resolved_alignment.block, + }; let block_axis_solver = AbsoluteAxisSolver { + axis: AxisDirection::Block, containing_size: cbbs, padding_border_sum: pbm.padding_border_sums.block, computed_margin_start: pbm.margin.block_start, computed_margin_end: pbm.margin.block_end, avoid_negative_margin_start: false, - box_offsets: &shared_fragment.box_offsets.block, + box_offsets: block_box_offsets, + static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Block), + alignment: block_alignment, }; let overconstrained = LogicalVec2 { inline: inline_axis_solver.is_overconstrained_for_size(computed_size.inline), @@ -560,7 +558,7 @@ impl HoistedAbsolutelyPositionedBox { // https://drafts.csswg.org/css2/#min-max-heights let min_size = non_replaced .style - .content_min_box_size(&containing_block.into(), &pbm) + .content_min_box_size(&indefinite_containing_block, &pbm) .map(|t| t.map(Au::from).auto_is(Au::zero)); let max_size = non_replaced .style @@ -720,7 +718,7 @@ impl HoistedAbsolutelyPositionedBox { }, }; - let content_rect = LogicalRect { + let mut content_rect = LogicalRect { start_corner: LogicalVec2 { inline: inline_start, block: block_start, @@ -728,6 +726,13 @@ impl HoistedAbsolutelyPositionedBox { size: content_size, }; + let margin_box_rect = content_rect + .inflate(&pbm.padding) + .inflate(&pbm.border) + .inflate(&margin); + block_axis_solver.solve_alignment(margin_box_rect, &mut content_rect); + inline_axis_solver.solve_alignment(margin_box_rect, &mut content_rect); + let physical_overconstrained = overconstrained.to_physical_size(containing_block.effective_writing_mode()); @@ -754,10 +759,7 @@ impl HoistedAbsolutelyPositionedBox { // other elements. If any of them have a static start position though, we need to // adjust it to account for the start corner of this absolute. positioning_context.adjust_static_position_of_hoisted_fragments_with_offset( - &new_fragment - .content_rect - .origin - .to_logical(containing_block_writing_mode), + &new_fragment.content_rect.origin.to_vector(), PositioningContextLength::zero(), ); @@ -768,6 +770,42 @@ impl HoistedAbsolutelyPositionedBox { } } +#[derive(Clone, Copy)] +struct RectAxis { + origin: Au, + length: Au, +} + +impl LogicalRect { + fn get_axis(&self, axis: AxisDirection) -> RectAxis { + match axis { + AxisDirection::Block => RectAxis { + origin: self.start_corner.block, + length: self.size.block, + }, + AxisDirection::Inline => RectAxis { + origin: self.start_corner.inline, + length: self.size.inline, + }, + } + } +} + +#[derive(Debug)] +struct AbsoluteBoxOffsets<'a> { + start: LengthPercentageOrAuto<'a>, + end: LengthPercentageOrAuto<'a>, +} + +impl AbsoluteBoxOffsets<'_> { + pub(crate) fn both_specified(&self) -> bool { + !self.start.is_auto() && !self.end.is_auto() + } + + pub(crate) fn either_specified(&self) -> bool { + !self.start.is_auto() || !self.end.is_auto() + } +} enum Anchor { Start(Au), End(Au), @@ -781,12 +819,15 @@ struct AxisResult { } struct AbsoluteAxisSolver<'a> { + axis: AxisDirection, containing_size: Au, padding_border_sum: Au, computed_margin_start: AuOrAuto, computed_margin_end: AuOrAuto, avoid_negative_margin_start: bool, - box_offsets: &'a AbsoluteBoxOffsets, + box_offsets: AbsoluteBoxOffsets<'a>, + static_position_rect_axis: RectAxis, + alignment: AlignFlags, } impl<'a> AbsoluteAxisSolver<'a> { @@ -802,14 +843,17 @@ impl<'a> AbsoluteAxisSolver<'a> { /// /// In the replaced case, `size` is never `Auto`. fn solve_for_size(&self, computed_size: AuOrAuto) -> AxisResult { - match self.box_offsets { - AbsoluteBoxOffsets::StaticStart { start } => AxisResult { - anchor: Anchor::Start(*start), + match ( + self.box_offsets.start.non_auto(), + self.box_offsets.end.non_auto(), + ) { + (None, None) => AxisResult { + anchor: Anchor::Start(self.static_position_rect_axis.origin), size: computed_size, margin_start: self.computed_margin_start.auto_is(Au::zero), margin_end: self.computed_margin_end.auto_is(Au::zero), }, - AbsoluteBoxOffsets::Start { start } => AxisResult { + (Some(start), None) => AxisResult { anchor: Anchor::Start( start .percentage_relative_to(self.containing_size.into()) @@ -819,7 +863,7 @@ impl<'a> AbsoluteAxisSolver<'a> { margin_start: self.computed_margin_start.auto_is(Au::zero), margin_end: self.computed_margin_end.auto_is(Au::zero), }, - AbsoluteBoxOffsets::End { end } => AxisResult { + (None, Some(end)) => AxisResult { anchor: Anchor::End( end.percentage_relative_to(self.containing_size.into()) .into(), @@ -828,7 +872,7 @@ impl<'a> AbsoluteAxisSolver<'a> { margin_start: self.computed_margin_start.auto_is(Au::zero), margin_end: self.computed_margin_end.auto_is(Au::zero), }, - AbsoluteBoxOffsets::Both { start, end } => { + (Some(start), Some(end)) => { let start = start.percentage_relative_to(self.containing_size.into()); let end = end.percentage_relative_to(self.containing_size.into()); @@ -894,6 +938,66 @@ impl<'a> AbsoluteAxisSolver<'a> { !self.computed_margin_start.is_auto() && !self.computed_margin_end.is_auto() } + + fn origin_for_alignment_or_justification(&self, margin_box_axis: RectAxis) -> Option { + let alignment_container = match ( + self.box_offsets.start.non_auto(), + self.box_offsets.end.non_auto(), + ) { + (None, None) => self.static_position_rect_axis, + (Some(start), Some(end)) => { + let start = start.percentage_relative_to(self.containing_size.into()); + let end = end.percentage_relative_to(self.containing_size.into()); + + RectAxis { + origin: start.into(), + length: self.containing_size - (end + start).into(), + } + }, + _ => return None, + }; + + let mut value_after_safety = self.alignment.value(); + if self.alignment.flags() == AlignFlags::SAFE && + margin_box_axis.length > alignment_container.length + { + value_after_safety = AlignFlags::START; + } + + match value_after_safety { + AlignFlags::CENTER | AlignFlags::SPACE_AROUND | AlignFlags::SPACE_EVENLY => Some( + alignment_container.origin + + ((alignment_container.length - margin_box_axis.length) / 2), + ), + AlignFlags::FLEX_END | AlignFlags::END => Some( + alignment_container.origin + alignment_container.length - margin_box_axis.length, + ), + _ => None, + } + } + + fn solve_alignment( + &self, + margin_box_rect: LogicalRect, + content_box_rect: &mut LogicalRect, + ) { + let Some(new_origin) = + self.origin_for_alignment_or_justification(margin_box_rect.get_axis(self.axis)) + else { + return; + }; + + match self.axis { + AxisDirection::Block => { + content_box_rect.start_corner.block += + new_origin - margin_box_rect.start_corner.block + }, + AxisDirection::Inline => { + content_box_rect.start_corner.inline += + new_origin - margin_box_rect.start_corner.inline + }, + } + } } fn vec_append_owned(a: &mut Vec, mut b: Vec) { diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index 2e44f440e70..d359acc1178 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -15,10 +15,13 @@ use style::properties::longhands::column_span::computed_value::T as ColumnSpan; use style::properties::ComputedValues; use style::values::computed::basic_shape::ClipPath; use style::values::computed::image::Image as ComputedImageLayer; -use style::values::computed::{Length, LengthPercentage, NonNegativeLengthPercentage, Size}; +use style::values::computed::{ + AlignItems, Length, LengthPercentage, NonNegativeLengthPercentage, Size, +}; use style::values::generics::box_::Perspective; use style::values::generics::length::MaxSize; use style::values::generics::position::{GenericAspectRatio, PreferredRatio}; +use style::values::specified::align::AlignFlags; use style::values::specified::{box_ as stylo, Overflow}; use style::values::CSSFloat; use style::Zero; @@ -283,6 +286,11 @@ pub(crate) trait ComputedValuesExt { fn background_is_transparent(&self) -> bool; fn get_webrender_primitive_flags(&self) -> wr::PrimitiveFlags; fn bidi_control_chars(&self) -> (&'static str, &'static str); + fn resolve_align_self( + &self, + resolved_auto_value: AlignItems, + resolved_normal_value: AlignItems, + ) -> AlignItems; } impl ComputedValuesExt for ComputedValues { @@ -873,6 +881,18 @@ impl ComputedValuesExt for ComputedValues { (UnicodeBidi::Plaintext, _) => ("\u{2068}", "\u{2069}"), } } + + fn resolve_align_self( + &self, + resolved_auto_value: AlignItems, + resolved_normal_value: AlignItems, + ) -> AlignItems { + match self.clone_align_self().0 .0 { + AlignFlags::AUTO => resolved_auto_value, + AlignFlags::NORMAL => resolved_normal_value, + value => AlignItems(value), + } + } } impl From for Display { diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs index 8dbadb3503c..713ad684d1c 100644 --- a/components/layout_2020/table/layout.rs +++ b/components/layout_2020/table/layout.rs @@ -1646,7 +1646,6 @@ impl<'a> TableLayout<'a> { let caption_fragment = Fragment::Box(caption_fragment); positioning_context.adjust_static_position_of_hoisted_fragments( &caption_fragment, - table_writing_mode, original_positioning_context_length, ); Some(caption_fragment) @@ -1683,7 +1682,6 @@ impl<'a> TableLayout<'a> { let grid_fragment = Fragment::Box(grid_fragment); positioning_context.adjust_static_position_of_hoisted_fragments( &grid_fragment, - table_writing_mode, original_positioning_context_length, ); table_layout.fragments.push(grid_fragment); @@ -1719,7 +1717,6 @@ impl<'a> TableLayout<'a> { let caption_fragment = Fragment::Box(caption_fragment); positioning_context.adjust_static_position_of_hoisted_fragments( &caption_fragment, - table_writing_mode, original_positioning_context_length, ); Some(caption_fragment) @@ -2591,10 +2588,12 @@ impl TableSlotCell { // TODO(mrobinson): This is correct for absolutes that are direct children of the table // cell, but wrong for absolute fragments that are more deeply nested in the hierarchy of // fragments. + let physical_cell_rect = + cell_content_rect.to_physical(table_style.effective_writing_mode()); layout .positioning_context .adjust_static_position_of_hoisted_fragments_with_offset( - &cell_content_rect.start_corner, + &physical_cell_rect.origin.to_vector(), PositioningContextLength::zero(), ); positioning_context.append(layout.positioning_context); @@ -2603,7 +2602,7 @@ impl TableSlotCell { base_fragment_info, self.style.clone(), vec![Fragment::Positioning(vertical_align_fragment)], - cell_content_rect.to_physical(table_style.effective_writing_mode()), + physical_cell_rect, layout .padding .to_physical(table_style.effective_writing_mode()), diff --git a/tests/wpt/meta/css/css-align/abspos/safe-align-self-htb.html.ini b/tests/wpt/meta/css/css-align/abspos/safe-align-self-htb.html.ini deleted file mode 100644 index 548fb403314..00000000000 --- a/tests/wpt/meta/css/css-align/abspos/safe-align-self-htb.html.ini +++ /dev/null @@ -1,36 +0,0 @@ -[safe-align-self-htb.html] - [.item 7] - expected: FAIL - - [.item 8] - expected: FAIL - - [.item 9] - expected: FAIL - - [.item 10] - expected: FAIL - - [.item 11] - expected: FAIL - - [.item 12] - expected: FAIL - - [.item 19] - expected: FAIL - - [.item 20] - expected: FAIL - - [.item 21] - expected: FAIL - - [.item 22] - expected: FAIL - - [.item 23] - expected: FAIL - - [.item 24] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/flex-abspos-staticpos-fallback-justify-content-001.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/flex-abspos-staticpos-fallback-justify-content-001.html.ini deleted file mode 100644 index 6b3686e412c..00000000000 --- a/tests/wpt/meta/css/css-flexbox/abspos/flex-abspos-staticpos-fallback-justify-content-001.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flex-abspos-staticpos-fallback-justify-content-001.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini index 765783fa81c..4f75db4711a 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini @@ -8,24 +8,12 @@ [.flexbox 34] expected: FAIL - [.flexbox 35] - expected: FAIL - [.flexbox 36] expected: FAIL [.flexbox 37] expected: FAIL - [.flexbox 30] - expected: FAIL - - [.flexbox 31] - expected: FAIL - - [.flexbox 33] - expected: FAIL - [.flexbox 89] expected: FAIL @@ -53,18 +41,6 @@ [.flexbox 17] expected: FAIL - [.flexbox 15] - expected: FAIL - - [.flexbox 12] - expected: FAIL - - [.flexbox 13] - expected: FAIL - - [.flexbox 10] - expected: FAIL - [.flexbox 18] expected: FAIL @@ -116,9 +92,6 @@ [.flexbox 67] expected: FAIL - [.flexbox 66] - expected: FAIL - [.flexbox 65] expected: FAIL @@ -149,9 +122,6 @@ [.flexbox 75] expected: FAIL - [.flexbox 76] - expected: FAIL - [.flexbox 77] expected: FAIL @@ -188,9 +158,6 @@ [.flexbox 44] expected: FAIL - [.flexbox 47] - expected: FAIL - [.flexbox 46] expected: FAIL @@ -227,21 +194,9 @@ [.flexbox 104] expected: FAIL - [.flexbox 5] - expected: FAIL - [.flexbox 6] expected: FAIL - [.flexbox 2] - expected: FAIL - - [.flexbox 3] - expected: FAIL - - [.flexbox 8] - expected: FAIL - [.flexbox 9] expected: FAIL @@ -263,35 +218,38 @@ [.flexbox 56] expected: FAIL - [.flexbox 57] - expected: FAIL - [.flexbox 54] expected: FAIL [.flexbox 55] expected: FAIL - [.flexbox 28] - expected: FAIL - [.flexbox 27] expected: FAIL - [.flexbox 25] - expected: FAIL - [.flexbox 24] expected: FAIL - [.flexbox 23] - expected: FAIL - - [.flexbox 21] - expected: FAIL - [.flexbox 20] expected: FAIL [.flexbox 120] expected: FAIL + + [.flexbox 7] + expected: FAIL + + [.flexbox 26] + expected: FAIL + + [.flexbox 52] + expected: FAIL + + [.flexbox 71] + expected: FAIL + + [.flexbox 87] + expected: FAIL + + [.flexbox 106] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini index 2a7e30f8cf2..a02b4f5d68e 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini @@ -5,12 +5,6 @@ [.flexbox 4] expected: FAIL - [.flexbox 3] - expected: FAIL - - [.flexbox 2] - expected: FAIL - [.flexbox 8] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini index babfb27671f..093adb429a8 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini @@ -1,10 +1,4 @@ [position-absolute-012.html] - [.flexbox 38] - expected: FAIL - - [.flexbox 39] - expected: FAIL - [.flexbox 35] expected: FAIL @@ -38,9 +32,6 @@ [.flexbox 85] expected: FAIL - [.flexbox 84] - expected: FAIL - [.flexbox 86] expected: FAIL @@ -50,33 +41,15 @@ [.flexbox 14] expected: FAIL - [.flexbox 12] - expected: FAIL - [.flexbox 13] expected: FAIL - [.flexbox 10] - expected: FAIL - - [.flexbox 11] - expected: FAIL - - [.flexbox 18] - expected: FAIL - - [.flexbox 19] - expected: FAIL - [.flexbox 96] expected: FAIL [.flexbox 94] expected: FAIL - [.flexbox 92] - expected: FAIL - [.flexbox 93] expected: FAIL @@ -86,12 +59,6 @@ [.flexbox 91] expected: FAIL - [.flexbox 63] - expected: FAIL - - [.flexbox 62] - expected: FAIL - [.flexbox 61] expected: FAIL @@ -107,9 +74,6 @@ [.flexbox 69] expected: FAIL - [.flexbox 68] - expected: FAIL - [.flexbox 70] expected: FAIL @@ -122,9 +86,6 @@ [.flexbox 75] expected: FAIL - [.flexbox 76] - expected: FAIL - [.flexbox 77] expected: FAIL @@ -137,12 +98,6 @@ [.flexbox 44] expected: FAIL - [.flexbox 47] - expected: FAIL - - [.flexbox 46] - expected: FAIL - [.flexbox 41] expected: FAIL @@ -152,21 +107,12 @@ [.flexbox 49] expected: FAIL - [.flexbox 4] - expected: FAIL - [.flexbox 5] expected: FAIL [.flexbox 6] expected: FAIL - [.flexbox 2] - expected: FAIL - - [.flexbox 3] - expected: FAIL - [.flexbox 8] expected: FAIL @@ -185,24 +131,9 @@ [.flexbox 57] expected: FAIL - [.flexbox 54] - expected: FAIL - - [.flexbox 55] - expected: FAIL - [.flexbox 29] expected: FAIL - [.flexbox 28] - expected: FAIL - - [.flexbox 27] - expected: FAIL - - [.flexbox 26] - expected: FAIL - [.flexbox 24] expected: FAIL @@ -212,5 +143,50 @@ [.flexbox 21] expected: FAIL - [.flexbox 20] + [.flexbox 7] + expected: FAIL + + [.flexbox 15] + expected: FAIL + + [.flexbox 23] + expected: FAIL + + [.flexbox 31] + expected: FAIL + + [.flexbox 34] + expected: FAIL + + [.flexbox 40] + expected: FAIL + + [.flexbox 42] + expected: FAIL + + [.flexbox 48] + expected: FAIL + + [.flexbox 50] + expected: FAIL + + [.flexbox 56] + expected: FAIL + + [.flexbox 58] + expected: FAIL + + [.flexbox 64] + expected: FAIL + + [.flexbox 71] + expected: FAIL + + [.flexbox 79] + expected: FAIL + + [.flexbox 87] + expected: FAIL + + [.flexbox 95] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini index 0c429395c15..e3d9ec89029 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini @@ -5,9 +5,6 @@ [.flexbox 302] expected: FAIL - [.flexbox 305] - expected: FAIL - [.flexbox 304] expected: FAIL @@ -17,12 +14,6 @@ [.flexbox 306] expected: FAIL - [.flexbox 38] - expected: FAIL - - [.flexbox 39] - expected: FAIL - [.flexbox 34] expected: FAIL @@ -32,9 +23,6 @@ [.flexbox 36] expected: FAIL - [.flexbox 37] - expected: FAIL - [.flexbox 32] expected: FAIL @@ -53,9 +41,6 @@ [.flexbox 393] expected: FAIL - [.flexbox 390] - expected: FAIL - [.flexbox 391] expected: FAIL @@ -65,21 +50,9 @@ [.flexbox 275] expected: FAIL - [.flexbox 274] - expected: FAIL - [.flexbox 277] expected: FAIL - [.flexbox 276] - expected: FAIL - - [.flexbox 272] - expected: FAIL - - [.flexbox 374] - expected: FAIL - [.flexbox 375] expected: FAIL @@ -95,9 +68,6 @@ [.flexbox 373] expected: FAIL - [.flexbox 89] - expected: FAIL - [.flexbox 80] expected: FAIL @@ -107,27 +77,15 @@ [.flexbox 82] expected: FAIL - [.flexbox 85] - expected: FAIL - [.flexbox 84] expected: FAIL - [.flexbox 87] - expected: FAIL - - [.flexbox 86] - expected: FAIL - [.flexbox 182] expected: FAIL [.flexbox 180] expected: FAIL - [.flexbox 187] - expected: FAIL - [.flexbox 186] expected: FAIL @@ -137,33 +95,15 @@ [.flexbox 184] expected: FAIL - [.flexbox 189] - expected: FAIL - [.flexbox 118] expected: FAIL [.flexbox 119] expected: FAIL - [.flexbox 111] - expected: FAIL - - [.flexbox 112] - expected: FAIL - - [.flexbox 113] - expected: FAIL - - [.flexbox 114] - expected: FAIL - [.flexbox 116] expected: FAIL - [.flexbox 239] - expected: FAIL - [.flexbox 238] expected: FAIL @@ -176,15 +116,9 @@ [.flexbox 232] expected: FAIL - [.flexbox 235] - expected: FAIL - [.flexbox 234] expected: FAIL - [.flexbox 237] - expected: FAIL - [.flexbox 331] expected: FAIL @@ -212,9 +146,6 @@ [.flexbox 46] expected: FAIL - [.flexbox 41] - expected: FAIL - [.flexbox 43] expected: FAIL @@ -224,9 +155,6 @@ [.flexbox 248] expected: FAIL - [.flexbox 249] - expected: FAIL - [.flexbox 244] expected: FAIL @@ -236,9 +164,6 @@ [.flexbox 246] expected: FAIL - [.flexbox 247] - expected: FAIL - [.flexbox 240] expected: FAIL @@ -302,21 +227,9 @@ [.flexbox 389] expected: FAIL - [.flexbox 388] - expected: FAIL - - [.flexbox 200] - expected: FAIL - [.flexbox 201] expected: FAIL - [.flexbox 202] - expected: FAIL - - [.flexbox 204] - expected: FAIL - [.flexbox 205] expected: FAIL @@ -335,24 +248,15 @@ [.flexbox 363] expected: FAIL - [.flexbox 362] - expected: FAIL - [.flexbox 361] expected: FAIL [.flexbox 360] expected: FAIL - [.flexbox 99] - expected: FAIL - [.flexbox 96] expected: FAIL - [.flexbox 97] - expected: FAIL - [.flexbox 94] expected: FAIL @@ -368,9 +272,6 @@ [.flexbox 72] expected: FAIL - [.flexbox 73] - expected: FAIL - [.flexbox 428] expected: FAIL @@ -380,15 +281,9 @@ [.flexbox 420] expected: FAIL - [.flexbox 421] - expected: FAIL - [.flexbox 422] expected: FAIL - [.flexbox 423] - expected: FAIL - [.flexbox 424] expected: FAIL @@ -398,27 +293,12 @@ [.flexbox 427] expected: FAIL - [.flexbox 293] - expected: FAIL - - [.flexbox 109] - expected: FAIL - [.flexbox 108] expected: FAIL [.flexbox 103] expected: FAIL - [.flexbox 102] - expected: FAIL - - [.flexbox 101] - expected: FAIL - - [.flexbox 100] - expected: FAIL - [.flexbox 106] expected: FAIL @@ -440,9 +320,6 @@ [.flexbox 327] expected: FAIL - [.flexbox 326] - expected: FAIL - [.flexbox 325] expected: FAIL @@ -455,30 +332,15 @@ [.flexbox 59] expected: FAIL - [.flexbox 52] - expected: FAIL - - [.flexbox 53] - expected: FAIL - - [.flexbox 50] - expected: FAIL - [.flexbox 56] expected: FAIL [.flexbox 57] expected: FAIL - [.flexbox 54] - expected: FAIL - [.flexbox 55] expected: FAIL - [.flexbox 259] - expected: FAIL - [.flexbox 258] expected: FAIL @@ -494,12 +356,6 @@ [.flexbox 253] expected: FAIL - [.flexbox 251] - expected: FAIL - - [.flexbox 411] - expected: FAIL - [.flexbox 410] expected: FAIL @@ -524,63 +380,30 @@ [.flexbox 171] expected: FAIL - [.flexbox 177] - expected: FAIL - [.flexbox 174] expected: FAIL - [.flexbox 175] - expected: FAIL - [.flexbox 178] expected: FAIL - [.flexbox 179] - expected: FAIL - - [.flexbox 16] - expected: FAIL - - [.flexbox 17] - expected: FAIL - - [.flexbox 14] - expected: FAIL - [.flexbox 11] expected: FAIL - [.flexbox 18] - expected: FAIL - [.flexbox 19] expected: FAIL [.flexbox 213] expected: FAIL - [.flexbox 212] - expected: FAIL - [.flexbox 211] expected: FAIL [.flexbox 217] expected: FAIL - [.flexbox 216] - expected: FAIL - - [.flexbox 214] - expected: FAIL - [.flexbox 352] expected: FAIL - [.flexbox 353] - expected: FAIL - [.flexbox 219] expected: FAIL @@ -599,21 +422,9 @@ [.flexbox 358] expected: FAIL - [.flexbox 62] - expected: FAIL - [.flexbox 67] expected: FAIL - [.flexbox 66] - expected: FAIL - - [.flexbox 65] - expected: FAIL - - [.flexbox 64] - expected: FAIL - [.flexbox 280] expected: FAIL @@ -623,12 +434,6 @@ [.flexbox 282] expected: FAIL - [.flexbox 284] - expected: FAIL - - [.flexbox 286] - expected: FAIL - [.flexbox 287] expected: FAIL @@ -641,42 +446,21 @@ [.flexbox 359] expected: FAIL - [.flexbox 288] - expected: FAIL - - [.flexbox 136] - expected: FAIL - - [.flexbox 134] - expected: FAIL - - [.flexbox 135] - expected: FAIL - [.flexbox 132] expected: FAIL - [.flexbox 133] - expected: FAIL - [.flexbox 130] expected: FAIL [.flexbox 131] expected: FAIL - [.flexbox 138] - expected: FAIL - [.flexbox 139] expected: FAIL [.flexbox 317] expected: FAIL - [.flexbox 314] - expected: FAIL - [.flexbox 315] expected: FAIL @@ -695,18 +479,6 @@ [.flexbox 69] expected: FAIL - [.flexbox 29] - expected: FAIL - - [.flexbox 27] - expected: FAIL - - [.flexbox 26] - expected: FAIL - - [.flexbox 25] - expected: FAIL - [.flexbox 24] expected: FAIL @@ -722,15 +494,9 @@ [.flexbox 269] expected: FAIL - [.flexbox 263] - expected: FAIL - [.flexbox 260] expected: FAIL - [.flexbox 261] - expected: FAIL - [.flexbox 266] expected: FAIL @@ -749,21 +515,12 @@ [.flexbox 404] expected: FAIL - [.flexbox 402] - expected: FAIL - - [.flexbox 400] - expected: FAIL - [.flexbox 401] expected: FAIL [.flexbox 190] expected: FAIL - [.flexbox 191] - expected: FAIL - [.flexbox 192] expected: FAIL @@ -788,18 +545,9 @@ [.flexbox 169] expected: FAIL - [.flexbox 168] - expected: FAIL - [.flexbox 165] expected: FAIL - [.flexbox 164] - expected: FAIL - - [.flexbox 166] - expected: FAIL - [.flexbox 161] expected: FAIL @@ -812,18 +560,9 @@ [.flexbox 226] expected: FAIL - [.flexbox 227] - expected: FAIL - - [.flexbox 225] - expected: FAIL - [.flexbox 222] expected: FAIL - [.flexbox 223] - expected: FAIL - [.flexbox 220] expected: FAIL @@ -836,9 +575,6 @@ [.flexbox 347] expected: FAIL - [.flexbox 341] - expected: FAIL - [.flexbox 340] expected: FAIL @@ -857,15 +593,6 @@ [.flexbox 299] expected: FAIL - [.flexbox 74] - expected: FAIL - - [.flexbox 75] - expected: FAIL - - [.flexbox 77] - expected: FAIL - [.flexbox 292] expected: FAIL @@ -887,33 +614,15 @@ [.flexbox 368] expected: FAIL - [.flexbox 4] - expected: FAIL - - [.flexbox 5] - expected: FAIL - - [.flexbox 6] - expected: FAIL - [.flexbox 7] expected: FAIL - [.flexbox 2] - expected: FAIL - [.flexbox 8] expected: FAIL [.flexbox 9] expected: FAIL - [.flexbox 154] - expected: FAIL - - [.flexbox 156] - expected: FAIL - [.flexbox 157] expected: FAIL @@ -923,9 +632,6 @@ [.flexbox 151] expected: FAIL - [.flexbox 152] - expected: FAIL - [.flexbox 153] expected: FAIL @@ -938,29 +644,221 @@ [.flexbox 408] expected: FAIL - [.flexbox 409] - expected: FAIL - - [.flexbox 121] - expected: FAIL - [.flexbox 120] expected: FAIL - [.flexbox 123] - expected: FAIL - - [.flexbox 122] - expected: FAIL - - [.flexbox 124] - expected: FAIL - [.flexbox 127] expected: FAIL - [.flexbox 126] - expected: FAIL - [.flexbox 129] expected: FAIL + + [.flexbox 10] + expected: FAIL + + [.flexbox 12] + expected: FAIL + + [.flexbox 20] + expected: FAIL + + [.flexbox 31] + expected: FAIL + + [.flexbox 33] + expected: FAIL + + [.flexbox 47] + expected: FAIL + + [.flexbox 58] + expected: FAIL + + [.flexbox 60] + expected: FAIL + + [.flexbox 68] + expected: FAIL + + [.flexbox 79] + expected: FAIL + + [.flexbox 81] + expected: FAIL + + [.flexbox 95] + expected: FAIL + + [.flexbox 107] + expected: FAIL + + [.flexbox 115] + expected: FAIL + + [.flexbox 117] + expected: FAIL + + [.flexbox 128] + expected: FAIL + + [.flexbox 142] + expected: FAIL + + [.flexbox 144] + expected: FAIL + + [.flexbox 146] + expected: FAIL + + [.flexbox 155] + expected: FAIL + + [.flexbox 160] + expected: FAIL + + [.flexbox 162] + expected: FAIL + + [.flexbox 167] + expected: FAIL + + [.flexbox 173] + expected: FAIL + + [.flexbox 176] + expected: FAIL + + [.flexbox 181] + expected: FAIL + + [.flexbox 183] + expected: FAIL + + [.flexbox 188] + expected: FAIL + + [.flexbox 194] + expected: FAIL + + [.flexbox 203] + expected: FAIL + + [.flexbox 208] + expected: FAIL + + [.flexbox 210] + expected: FAIL + + [.flexbox 215] + expected: FAIL + + [.flexbox 221] + expected: FAIL + + [.flexbox 224] + expected: FAIL + + [.flexbox 229] + expected: FAIL + + [.flexbox 231] + expected: FAIL + + [.flexbox 236] + expected: FAIL + + [.flexbox 241] + expected: FAIL + + [.flexbox 243] + expected: FAIL + + [.flexbox 250] + expected: FAIL + + [.flexbox 252] + expected: FAIL + + [.flexbox 257] + expected: FAIL + + [.flexbox 262] + expected: FAIL + + [.flexbox 264] + expected: FAIL + + [.flexbox 268] + expected: FAIL + + [.flexbox 270] + expected: FAIL + + [.flexbox 271] + expected: FAIL + + [.flexbox 273] + expected: FAIL + + [.flexbox 278] + expected: FAIL + + [.flexbox 283] + expected: FAIL + + [.flexbox 285] + expected: FAIL + + [.flexbox 298] + expected: FAIL + + [.flexbox 300] + expected: FAIL + + [.flexbox 308] + expected: FAIL + + [.flexbox 319] + expected: FAIL + + [.flexbox 321] + expected: FAIL + + [.flexbox 335] + expected: FAIL + + [.flexbox 346] + expected: FAIL + + [.flexbox 348] + expected: FAIL + + [.flexbox 356] + expected: FAIL + + [.flexbox 367] + expected: FAIL + + [.flexbox 369] + expected: FAIL + + [.flexbox 383] + expected: FAIL + + [.flexbox 395] + expected: FAIL + + [.flexbox 403] + expected: FAIL + + [.flexbox 405] + expected: FAIL + + [.flexbox 416] + expected: FAIL + + [.flexbox 430] + expected: FAIL + + [.flexbox 432] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-015.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-015.html.ini deleted file mode 100644 index 67ea4cdfde0..00000000000 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-015.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[position-absolute-015.html] - [#abspos 1] - expected: FAIL - diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-containing-block-001.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-containing-block-001.html.ini deleted file mode 100644 index 403c792b263..00000000000 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-containing-block-001.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[position-absolute-containing-block-001.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-position/position-absolute-center-003.html.ini b/tests/wpt/meta/css/css-position/position-absolute-center-003.html.ini deleted file mode 100644 index 4bee82c7adc..00000000000 --- a/tests/wpt/meta/css/css-position/position-absolute-center-003.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[position-absolute-center-003.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-position/position-absolute-center-004.html.ini b/tests/wpt/meta/css/css-position/position-absolute-center-004.html.ini deleted file mode 100644 index edfcd812049..00000000000 --- a/tests/wpt/meta/css/css-position/position-absolute-center-004.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[position-absolute-center-004.html] - expected: FAIL