diff --git a/components/layout/flexbox/layout.rs b/components/layout/flexbox/layout.rs index 7044583fa09..24fba75d5b7 100644 --- a/components/layout/flexbox/layout.rs +++ b/components/layout/flexbox/layout.rs @@ -2147,7 +2147,7 @@ impl FlexItem<'_> { #[inline] fn is_table(&self) -> bool { - self.box_.is_table() + self.box_.independent_formatting_context.is_table() } } @@ -2225,7 +2225,7 @@ impl FlexItemBox { .map(|v| Au::zero().max(v - pbm_auto_is_zero.cross)), }; - let is_table = self.is_table(); + let is_table = self.independent_formatting_context.is_table(); let tentative_cross_content_size = if cross_axis_is_item_block_axis { self.independent_formatting_context .tentative_block_content_size(preferred_aspect_ratio) @@ -2718,12 +2718,4 @@ impl FlexItemBox { }, } } - - #[inline] - fn is_table(&self) -> bool { - match &self.independent_formatting_context.contents { - IndependentFormattingContextContents::NonReplaced(content) => content.is_table(), - IndependentFormattingContextContents::Replaced(_) => false, - } - } } diff --git a/components/layout/flow/float.rs b/components/layout/flow/float.rs index bb6c7ca8983..77e29435aaa 100644 --- a/components/layout/flow/float.rs +++ b/components/layout/flow/float.rs @@ -1066,36 +1066,6 @@ impl SequentialLayoutState { .map(|offset| offset - self.position_with_zero_clearance(block_start_margin)) } - /// A block that is replaced or establishes an independent formatting context can't overlap floats, - /// it has to be placed next to them, and may get some clearance if there isn't enough space. - /// Given such a block with the provided 'clear', 'block_start_margin', 'pbm' and 'object_size', - /// this method finds an area that is big enough and doesn't overlap floats. - /// It returns a tuple with: - /// - The clearance amount (if any), which includes both the effect of 'clear' - /// and the extra space to avoid floats. - /// - The LogicalRect in which the block can be placed without overlapping floats. - pub(crate) fn calculate_clearance_and_inline_adjustment( - &self, - clear: Clear, - block_start_margin: &CollapsedMargin, - pbm: &PaddingBorderMargin, - object_size: LogicalVec2, - ) -> (Option, LogicalRect) { - // First compute the clear position required by the 'clear' property. - // The code below may then add extra clearance when the element can't fit - // next to floats not covered by 'clear'. - let clear_position = self.calculate_clear_position(clear, block_start_margin); - let ceiling = - clear_position.unwrap_or_else(|| self.position_without_clearance(block_start_margin)); - let mut placement = PlacementAmongFloats::new(&self.floats, ceiling, object_size, pbm); - let placement_rect = placement.place(); - let position = &placement_rect.start_corner; - let has_clearance = clear_position.is_some() || position.block > ceiling; - let clearance = has_clearance - .then(|| position.block - self.position_with_zero_clearance(block_start_margin)); - (clearance, placement_rect) - } - /// Adds a new adjoining margin. pub(crate) fn adjoin_assign(&mut self, margin: &CollapsedMargin) { self.current_margin.adjoin_assign(margin) diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs index a9f57b2151a..66e9c29218a 100644 --- a/components/layout/flow/mod.rs +++ b/components/layout/flow/mod.rs @@ -30,7 +30,6 @@ use crate::flow::float::{ }; use crate::formatting_contexts::{ Baselines, IndependentFormattingContext, IndependentFormattingContextContents, - IndependentNonReplacedContents, }; use crate::fragment_tree::{ BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags, @@ -41,9 +40,8 @@ use crate::geom::{ }; use crate::layout_box_base::{CacheableLayoutResult, LayoutBoxBase}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength}; -use crate::replaced::ReplacedContents; use crate::sizing::{self, ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; -use crate::style_ext::{ContentBoxSizesAndPBM, LayoutStyle, PaddingBorderMargin}; +use crate::style_ext::{AspectRatio, ContentBoxSizesAndPBM, LayoutStyle, PaddingBorderMargin}; use crate::{ ConstraintSpace, ContainingBlock, ContainingBlockSize, IndefiniteContainingBlock, SizeConstraint, @@ -956,11 +954,13 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context( depends_on_block_constraints, available_block_size, justify_self, + .. } = solve_containing_block_padding_and_border_for_in_flow_box( containing_block, &layout_style, get_inline_content_sizes, ignore_block_margins_for_stretch, + None, ); let ResolvedMargins { margin, @@ -1178,15 +1178,16 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context( .with_block_margins_collapsed_with_children(block_margins_collapsed_with_children) } -impl IndependentNonReplacedContents { - /// Lay out a normal in flow non-replaced block that establishes an independent +impl IndependentFormattingContext { + /// Lay out an in-flow block-level box that establishes an independent /// formatting context in its containing formatting context. /// /// - + /// - /// - + /// - pub(crate) fn layout_in_flow_block_level( &self, - base: &LayoutBoxBase, layout_context: &LayoutContext, positioning_context: &mut PositioningContext, containing_block: &ContainingBlock, @@ -1195,7 +1196,6 @@ impl IndependentNonReplacedContents { ) -> BoxFragment { if let Some(sequential_layout_state) = sequential_layout_state { return self.layout_in_flow_block_level_sequentially( - base, layout_context, positioning_context, containing_block, @@ -1205,10 +1205,10 @@ impl IndependentNonReplacedContents { } let get_inline_content_sizes = |constraint_space: &ConstraintSpace| { - base.inline_content_sizes(layout_context, constraint_space, self) + self.inline_content_sizes(layout_context, constraint_space) .sizes }; - let layout_style = self.layout_style(base); + let layout_style = self.layout_style(); let ContainingBlockPaddingAndBorder { containing_block: containing_block_for_children, pbm, @@ -1216,11 +1216,13 @@ impl IndependentNonReplacedContents { depends_on_block_constraints, available_block_size, justify_self, + preferred_aspect_ratio, } = solve_containing_block_padding_and_border_for_in_flow_box( containing_block, &layout_style, get_inline_content_sizes, ignore_block_margins_for_stretch, + Some(self), ); let lazy_block_size = LazySize::new( @@ -1237,7 +1239,7 @@ impl IndependentNonReplacedContents { positioning_context, &containing_block_for_children, containing_block, - base, + preferred_aspect_ratio, false, /* depends_on_block_constraints */ &lazy_block_size, ); @@ -1268,7 +1270,7 @@ impl IndependentNonReplacedContents { let block_margins_collapsed_with_children = CollapsedBlockMargins::from_margin(&margin); let containing_block_writing_mode = containing_block.style.writing_mode; - let mut base_fragment_info = base.base_fragment_info; + let mut base_fragment_info = self.base.base_fragment_info; if depends_on_block_constraints { base_fragment_info.flags.insert( FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM, @@ -1276,7 +1278,7 @@ impl IndependentNonReplacedContents { } BoxFragment::new( base_fragment_info, - base.style.clone(), + self.base.style.clone(), layout.fragments, content_rect.as_physical(Some(containing_block)), pbm.padding.to_physical(containing_block_writing_mode), @@ -1294,14 +1296,13 @@ impl IndependentNonReplacedContents { /// layout concerns, such clearing and placing the content next to floats. fn layout_in_flow_block_level_sequentially( &self, - base: &LayoutBoxBase, layout_context: &LayoutContext<'_>, positioning_context: &mut PositioningContext, containing_block: &ContainingBlock<'_>, sequential_layout_state: &mut SequentialLayoutState, ignore_block_margins_for_stretch: LogicalSides1D, ) -> BoxFragment { - let style = &base.style; + let style = &self.base.style; let containing_block_writing_mode = containing_block.style.writing_mode; let ContentBoxSizesAndPBM { content_box_sizes, @@ -1309,7 +1310,7 @@ impl IndependentNonReplacedContents { depends_on_block_constraints, .. } = self - .layout_style(base) + .layout_style() .content_box_sizes_and_padding_border_margin(&containing_block.into()); let (margin_block_start, margin_block_end) = @@ -1341,16 +1342,34 @@ impl IndependentNonReplacedContents { sequential_layout_state.position_without_clearance(&collapsed_margin_block_start) }); - // Then compute a tentative block size, only taking extrinsic values into account. + // Then compute a tentative block size. let pbm_sums = pbm.sums_auto_is_zero(ignore_block_margins_for_stretch); let available_block_size = containing_block .size .block .to_definite() .map(|block_size| Au::zero().max(block_size - pbm_sums.block)); - let (preferred_block_size, min_block_size, max_block_size) = content_box_sizes - .block - .resolve_each_extrinsic(Size::FitContent, Au::zero(), available_block_size); + let is_table = self.is_table(); + let preferred_aspect_ratio = self.preferred_aspect_ratio(&pbm.padding_border_sums); + let tentative_block_content_size = + self.tentative_block_content_size(preferred_aspect_ratio); + let (preferred_block_size, min_block_size, max_block_size) = + if let Some(block_content_size) = tentative_block_content_size { + let (preferred, min, max) = content_box_sizes.block.resolve_each( + Size::FitContent, + Au::zero, + available_block_size, + || block_content_size, + is_table, + ); + (Some(preferred), min, max) + } else { + content_box_sizes.block.resolve_each_extrinsic( + Size::FitContent, + Au::zero(), + available_block_size, + ) + }; let tentative_block_size = SizeConstraint::new(preferred_block_size, min_block_size, max_block_size); @@ -1359,18 +1378,18 @@ impl IndependentNonReplacedContents { let constraint_space = ConstraintSpace::new( tentative_block_size, style.writing_mode, - self.preferred_aspect_ratio(), + preferred_aspect_ratio, ); - base.inline_content_sizes(layout_context, &constraint_space, self) + self.inline_content_sizes(layout_context, &constraint_space) .sizes }; let justify_self = resolve_justify_self(style, containing_block.style); - let is_table = self.is_table(); + let is_replaced = self.is_replaced(); let compute_inline_size = |stretch_size| { content_box_sizes.inline.resolve( Direction::Inline, - automatic_inline_size(justify_self, is_table), + automatic_inline_size(justify_self, is_table, is_replaced), Au::zero, Some(stretch_size), get_inline_content_sizes, @@ -1412,7 +1431,7 @@ impl IndependentNonReplacedContents { style, }, containing_block, - base, + preferred_aspect_ratio, false, /* depends_on_block_constraints */ &lazy_block_size, ); @@ -1478,7 +1497,7 @@ impl IndependentNonReplacedContents { style, }, containing_block, - base, + preferred_aspect_ratio, false, /* depends_on_block_constraints */ &lazy_block_size, ); @@ -1568,7 +1587,7 @@ impl IndependentNonReplacedContents { size: content_size, }; - let mut base_fragment_info = base.base_fragment_info; + let mut base_fragment_info = self.base.base_fragment_info; if depends_on_block_constraints { base_fragment_info.flags.insert( FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM, @@ -1591,144 +1610,6 @@ impl IndependentNonReplacedContents { } } -impl ReplacedContents { - /// - /// - /// - fn layout_in_flow_block_level( - &self, - base: &LayoutBoxBase, - layout_context: &LayoutContext, - containing_block: &ContainingBlock, - mut sequential_layout_state: Option<&mut SequentialLayoutState>, - ignore_block_margins_for_stretch: LogicalSides1D, - ) -> BoxFragment { - let content_box_sizes_and_pbm = self - .layout_style(base) - .content_box_sizes_and_padding_border_margin(&containing_block.into()); - let pbm = &content_box_sizes_and_pbm.pbm; - let content_size = self.used_size_as_if_inline_element( - containing_block, - &base.style, - &content_box_sizes_and_pbm, - ignore_block_margins_for_stretch, - ); - - let margin_inline_start; - let margin_inline_end; - let effective_margin_inline_start; - let (margin_block_start, margin_block_end) = - solve_block_margins_for_in_flow_block_level(pbm); - let justify_self = resolve_justify_self(&base.style, containing_block.style); - - let containing_block_writing_mode = containing_block.style.writing_mode; - let physical_content_size = content_size.to_physical_size(containing_block_writing_mode); - let fragments = self.make_fragments(layout_context, &base.style, physical_content_size); - - let clearance; - if let Some(ref mut sequential_layout_state) = sequential_layout_state { - // From https://drafts.csswg.org/css2/#floats: - // "The border box of a table, a block-level replaced element, or an element in - // the normal flow that establishes a new block formatting context (such as an - // element with overflow other than visible) must not overlap the margin box of - // any floats in the same block formatting context as the element itself. If - // necessary, implementations should clear the said element by placing it below - // any preceding floats, but may place it adjacent to such floats if there is - // sufficient space. They may even make the border box of said element narrower - // than defined by section 10.3.3. CSS 2 does not define when a UA may put said - // element next to the float or by how much said element may become narrower." - let collapsed_margin_block_start = CollapsedMargin::new(margin_block_start); - let size = content_size + pbm.padding_border_sums; - let placement_rect; - (clearance, placement_rect) = sequential_layout_state - .calculate_clearance_and_inline_adjustment( - Clear::from_style_and_container_writing_mode( - &base.style, - containing_block.style.writing_mode, - ), - &collapsed_margin_block_start, - pbm, - size, - ); - ( - (margin_inline_start, margin_inline_end), - effective_margin_inline_start, - ) = solve_inline_margins_avoiding_floats( - sequential_layout_state, - containing_block, - pbm, - size.inline, - placement_rect, - justify_self, - ); - - // Clearance prevents margin collapse between this block and previous ones, - // so in that case collapse margins before adjoining them below. - if clearance.is_some() { - sequential_layout_state.collapse_margins(); - } - sequential_layout_state.adjoin_assign(&collapsed_margin_block_start); - - // Margins can never collapse into replaced elements. - sequential_layout_state.collapse_margins(); - sequential_layout_state - .advance_block_position(size.block + clearance.unwrap_or_else(Au::zero)); - sequential_layout_state.adjoin_assign(&CollapsedMargin::new(margin_block_end)); - } else { - clearance = None; - ( - (margin_inline_start, margin_inline_end), - effective_margin_inline_start, - ) = solve_inline_margins_for_in_flow_block_level( - containing_block, - pbm, - content_size.inline, - justify_self, - ); - }; - - let margin = LogicalSides { - inline_start: margin_inline_start, - inline_end: margin_inline_end, - block_start: margin_block_start, - block_end: margin_block_end, - }; - - let start_corner = LogicalVec2 { - block: pbm.padding.block_start + - pbm.border.block_start + - clearance.unwrap_or_else(Au::zero), - inline: pbm.padding.inline_start + - pbm.border.inline_start + - effective_margin_inline_start, - }; - let content_rect = LogicalRect { - start_corner, - size: content_size, - } - .as_physical(Some(containing_block)); - - let mut base_fragment_info = base.base_fragment_info; - if content_box_sizes_and_pbm.depends_on_block_constraints { - base_fragment_info.flags.insert( - FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM, - ); - } - - BoxFragment::new( - base_fragment_info, - base.style.clone(), - fragments, - content_rect, - pbm.padding.to_physical(containing_block_writing_mode), - pbm.border.to_physical(containing_block_writing_mode), - margin.to_physical(containing_block_writing_mode), - clearance, - ) - .with_block_margins_collapsed_with_children(CollapsedBlockMargins::from_margin(&margin)) - } -} - struct ContainingBlockPaddingAndBorder<'a> { containing_block: ContainingBlock<'a>, pbm: PaddingBorderMargin, @@ -1736,6 +1617,7 @@ struct ContainingBlockPaddingAndBorder<'a> { depends_on_block_constraints: bool, available_block_size: Option, justify_self: AlignFlags, + preferred_aspect_ratio: Option, } struct ResolvedMargins { @@ -1761,6 +1643,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( layout_style: &'a LayoutStyle, get_inline_content_sizes: impl FnOnce(&ConstraintSpace) -> ContentSizes, ignore_block_margins_for_stretch: LogicalSides1D, + context: Option<&IndependentFormattingContext>, ) -> ContainingBlockPaddingAndBorder<'a> { let style = layout_style.style(); if matches!(style.pseudo(), Some(PseudoElement::ServoAnonymousBox)) { @@ -1787,6 +1670,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( // The initial `justify-self` is `auto`, but use `normal` (behaving as `stretch`). // This is being discussed in . justify_self: AlignFlags::NORMAL, + preferred_aspect_ratio: None, }; } @@ -1806,13 +1690,32 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( .to_definite() .map(|block_size| Au::zero().max(block_size - pbm_sums.block)); + // TODO: support preferred aspect ratios on boxes that don't establish an independent + // formatting context. + let preferred_aspect_ratio = + context.and_then(|context| context.preferred_aspect_ratio(&pbm.padding_border_sums)); + let is_table = layout_style.is_table(); + // https://drafts.csswg.org/css2/#the-height-property // https://drafts.csswg.org/css2/visudet.html#min-max-heights - let tentative_block_size = content_box_sizes.block.resolve_extrinsic( - Size::FitContent, - Au::zero(), - available_block_size, - ); + let tentative_block_content_size = + context.and_then(|context| context.tentative_block_content_size(preferred_aspect_ratio)); + let tentative_block_size = if let Some(block_content_size) = tentative_block_content_size { + SizeConstraint::Definite(content_box_sizes.block.resolve( + Direction::Block, + Size::FitContent, + Au::zero, + available_block_size, + || block_content_size, + is_table, + )) + } else { + content_box_sizes.block.resolve_extrinsic( + Size::FitContent, + Au::zero(), + available_block_size, + ) + }; // https://drafts.csswg.org/css2/#the-width-property // https://drafts.csswg.org/css2/visudet.html#min-max-widths @@ -1820,14 +1723,14 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( get_inline_content_sizes(&ConstraintSpace::new( tentative_block_size, writing_mode, - None, /* TODO: support preferred aspect ratios on non-replaced boxes */ + preferred_aspect_ratio, )) }; let justify_self = resolve_justify_self(style, containing_block.style); - let is_table = layout_style.is_table(); + let is_replaced = context.is_some_and(|context| context.is_replaced()); let inline_size = content_box_sizes.inline.resolve( Direction::Inline, - automatic_inline_size(justify_self, is_table), + automatic_inline_size(justify_self, is_table, is_replaced), Au::zero, Some(available_inline_size), get_inline_content_sizes, @@ -1857,6 +1760,7 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( depends_on_block_constraints, available_block_size, justify_self, + preferred_aspect_ratio, } } @@ -1923,10 +1827,14 @@ fn resolve_justify_self(style: &ComputedValues, parent_style: &ComputedValues) - /// Determines the automatic size for the inline axis of a block-level box. /// #[inline] -fn automatic_inline_size(justify_self: AlignFlags, is_table: bool) -> Size { +fn automatic_inline_size( + justify_self: AlignFlags, + is_table: bool, + is_replaced: bool, +) -> Size { match justify_self { AlignFlags::STRETCH => Size::Stretch, - AlignFlags::NORMAL if !is_table => Size::Stretch, + AlignFlags::NORMAL if !is_table && !is_replaced => Size::Stretch, _ => Size::FitContent, } } @@ -2318,34 +2226,6 @@ pub(crate) struct IndependentFloatOrAtomicLayoutResult { } impl IndependentFormattingContext { - pub(crate) fn layout_in_flow_block_level( - &self, - layout_context: &LayoutContext, - positioning_context: &mut PositioningContext, - containing_block: &ContainingBlock, - sequential_layout_state: Option<&mut SequentialLayoutState>, - ignore_block_margins_for_stretch: LogicalSides1D, - ) -> BoxFragment { - match &self.contents { - IndependentFormattingContextContents::NonReplaced(contents) => contents - .layout_in_flow_block_level( - &self.base, - layout_context, - positioning_context, - containing_block, - sequential_layout_state, - ignore_block_margins_for_stretch, - ), - IndependentFormattingContextContents::Replaced(contents) => contents - .layout_in_flow_block_level( - &self.base, - layout_context, - containing_block, - sequential_layout_state, - ignore_block_margins_for_stretch, - ), - } - } pub(crate) fn layout_float_or_atomic_inline( &self, layout_context: &LayoutContext, diff --git a/components/layout/formatting_contexts.rs b/components/layout/formatting_contexts.rs index 8fe8bd7cba5..c32b43a3c9a 100644 --- a/components/layout/formatting_contexts.rs +++ b/components/layout/formatting_contexts.rs @@ -265,6 +265,48 @@ impl IndependentFormattingContext { IndependentFormattingContextContents::Replaced(..) => {}, } } + + #[allow(clippy::too_many_arguments)] + pub(crate) fn layout( + &self, + layout_context: &LayoutContext, + positioning_context: &mut PositioningContext, + containing_block_for_children: &ContainingBlock, + containing_block: &ContainingBlock, + preferred_aspect_ratio: Option, + depends_on_block_constraints: bool, + lazy_block_size: &LazySize, + ) -> CacheableLayoutResult { + match &self.contents { + IndependentFormattingContextContents::NonReplaced(content) => content.layout( + layout_context, + positioning_context, + containing_block_for_children, + containing_block, + &self.base, + depends_on_block_constraints, + lazy_block_size, + ), + IndependentFormattingContextContents::Replaced(content) => content.layout( + layout_context, + containing_block_for_children, + preferred_aspect_ratio, + &self.base, + depends_on_block_constraints, + lazy_block_size, + ), + } + } + + #[inline] + pub(crate) fn is_table(&self) -> bool { + matches!( + &self.contents, + IndependentFormattingContextContents::NonReplaced( + IndependentNonReplacedContents::Table(_) + ) + ) + } } impl IndependentNonReplacedContents { @@ -312,7 +354,7 @@ impl IndependentNonReplacedContents { skip_all )] #[allow(clippy::too_many_arguments)] - pub fn layout( + pub(crate) fn layout( &self, layout_context: &LayoutContext, positioning_context: &mut PositioningContext, @@ -378,11 +420,6 @@ impl IndependentNonReplacedContents { None } - #[inline] - pub(crate) fn is_table(&self) -> bool { - matches!(self, Self::Table(_)) - } - fn repair_style( &mut self, context: &SharedStyleContext, diff --git a/components/layout/replaced.rs b/components/layout/replaced.rs index 88c8c7ba63c..f5a7e7c41e1 100644 --- a/components/layout/replaced.rs +++ b/components/layout/replaced.rs @@ -26,11 +26,13 @@ use webrender_api::ImageKey; use crate::cell::ArcRefCell; use crate::context::{LayoutContext, LayoutImageCacheResult}; use crate::dom::NodeExt; -use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment}; -use crate::geom::{ - LogicalSides1D, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size, Sizes, +use crate::fragment_tree::{ + BaseFragmentInfo, CollapsedBlockMargins, Fragment, IFrameFragment, ImageFragment, }; -use crate::layout_box_base::LayoutBoxBase; +use crate::geom::{ + LazySize, LogicalSides1D, LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size, Sizes, +}; +use crate::layout_box_base::{CacheableLayoutResult, LayoutBoxBase}; use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult}; use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM, LayoutStyle}; use crate::{ConstraintSpace, ContainingBlock, SizeConstraint}; @@ -598,6 +600,40 @@ impl ReplacedContents { pub(crate) fn layout_style<'a>(&self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> { LayoutStyle::Default(&base.style) } + + pub(crate) fn layout( + &self, + layout_context: &LayoutContext, + containing_block_for_children: &ContainingBlock, + preferred_aspect_ratio: Option, + base: &LayoutBoxBase, + depends_on_block_constraints: bool, + lazy_block_size: &LazySize, + ) -> CacheableLayoutResult { + // TODO: consider caching the result in LayoutBoxBase like we do for non-replaced. + let writing_mode = base.style.writing_mode; + let inline_size = containing_block_for_children.size.inline; + let content_block_size = self.content_size( + Direction::Block, + preferred_aspect_ratio, + &|| SizeConstraint::Definite(inline_size), + &|| self.fallback_block_size(writing_mode), + ); + let size = LogicalVec2 { + inline: inline_size, + block: lazy_block_size.resolve(|| content_block_size), + } + .to_physical_size(writing_mode); + CacheableLayoutResult { + baselines: Default::default(), + collapsible_margins_in_children: CollapsedBlockMargins::zero(), + content_block_size, + content_inline_size_for_table: None, + depends_on_block_constraints, + fragments: self.make_fragments(layout_context, &base.style, size), + specific_layout_info: None, + } + } } impl ComputeInlineContentSizes for ReplacedContents { diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index e1f647c44b8..00d0e8309de 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -254076,6 +254076,32 @@ ], {} ] + ], + "replaced-next-to-float-1.html": [ + "b97f2ddba445dfdad6285691a509b3f2f7042b44", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "replaced-next-to-float-2.html": [ + "1a00846074ba376528d82836a644952773ce0edf", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] ] }, "svg-intrinsic-size-005.html": [ diff --git a/tests/wpt/tests/css/css-sizing/stretch/replaced-next-to-float-1.html b/tests/wpt/tests/css/css-sizing/stretch/replaced-next-to-float-1.html new file mode 100644 index 00000000000..b97f2ddba44 --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/replaced-next-to-float-1.html @@ -0,0 +1,23 @@ + + + + + + + + +

Test passes if there is a filled green square and no red.

+
+ +
+
+ +
diff --git a/tests/wpt/tests/css/css-sizing/stretch/replaced-next-to-float-2.html b/tests/wpt/tests/css/css-sizing/stretch/replaced-next-to-float-2.html new file mode 100644 index 00000000000..1a00846074b --- /dev/null +++ b/tests/wpt/tests/css/css-sizing/stretch/replaced-next-to-float-2.html @@ -0,0 +1,41 @@ + + + + + + + + + + +

Test passes if there is a filled green square and no red.

+
+ +
+
+ + + +
+
+
+
+
+ +