layout: Remove IndependentNonReplacedContents (#37971)

With the work to unify the layout logic for replaced and non-replaced
boxes (#37942), I think the `IndependentNonReplacedContents` enum does
no longer make much sense.

Therefore, this removes `IndependentNonReplacedContents`, merging its
values into `IndependentFormattingContextContents`.

The methods defined on `IndependentFormattingContextContents` can now be
on `IndependentFormattingContext`, in particular this implies that the
layout results of a replaced box will now be cached.

Testing: Unneeded (no behavior change)
This part of #37942

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-07-10 09:46:04 +02:00 committed by GitHub
parent 07247cd4fd
commit ff050b71fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 245 additions and 323 deletions

View file

@ -39,14 +39,7 @@ pub(crate) struct IndependentFormattingContext {
#[derive(Debug, MallocSizeOf)]
pub(crate) enum IndependentFormattingContextContents {
NonReplaced(IndependentNonReplacedContents),
Replaced(ReplacedContents),
}
// Private so that code outside of this module cannot match variants.
// It should got through methods instead.
#[derive(Debug, MallocSizeOf)]
pub(crate) enum IndependentNonReplacedContents {
Flow(BlockFormattingContext),
Flex(FlexContainer),
Grid(TaffyContainer),
@ -86,16 +79,18 @@ impl IndependentFormattingContext {
let contents = match display_inside {
DisplayInside::Flow { is_list_item } |
DisplayInside::FlowRoot { is_list_item } => {
IndependentNonReplacedContents::Flow(BlockFormattingContext::construct(
context,
node_and_style_info,
non_replaced_contents,
propagated_data,
is_list_item,
))
IndependentFormattingContextContents::Flow(
BlockFormattingContext::construct(
context,
node_and_style_info,
non_replaced_contents,
propagated_data,
is_list_item,
),
)
},
DisplayInside::Grid => {
IndependentNonReplacedContents::Grid(TaffyContainer::construct(
IndependentFormattingContextContents::Grid(TaffyContainer::construct(
context,
node_and_style_info,
non_replaced_contents,
@ -103,7 +98,7 @@ impl IndependentFormattingContext {
))
},
DisplayInside::Flex => {
IndependentNonReplacedContents::Flex(FlexContainer::construct(
IndependentFormattingContextContents::Flex(FlexContainer::construct(
context,
node_and_style_info,
non_replaced_contents,
@ -120,7 +115,7 @@ impl IndependentFormattingContext {
&node_and_style_info.style,
);
base_fragment_info.flags.insert(FragmentFlags::DO_NOT_PAINT);
IndependentNonReplacedContents::Table(Table::construct(
IndependentFormattingContextContents::Table(Table::construct(
context,
node_and_style_info,
table_grid_style,
@ -131,7 +126,7 @@ impl IndependentFormattingContext {
};
Self {
base: LayoutBoxBase::new(base_fragment_info, node_and_style_info.style.clone()),
contents: IndependentFormattingContextContents::NonReplaced(contents),
contents,
}
},
Contents::Replaced(contents) => {
@ -166,14 +161,8 @@ impl IndependentFormattingContext {
layout_context: &LayoutContext,
constraint_space: &ConstraintSpace,
) -> InlineContentSizesResult {
match &self.contents {
IndependentFormattingContextContents::NonReplaced(contents) => self
.base
.inline_content_sizes(layout_context, constraint_space, contents),
IndependentFormattingContextContents::Replaced(contents) => self
.base
.inline_content_sizes(layout_context, constraint_space, contents),
}
self.base
.inline_content_sizes(layout_context, constraint_space, &self.contents)
}
/// Computes the tentative intrinsic block sizes that may be needed while computing
@ -193,7 +182,6 @@ impl IndependentFormattingContext {
// See <https://github.com/w3c/csswg-drafts/issues/12333> regarding the difference
// in behavior for the replaced and non-replaced cases.
match &self.contents {
IndependentFormattingContextContents::NonReplaced(_) => None,
IndependentFormattingContextContents::Replaced(contents) => {
// For replaced elements with no ratio, the returned value doesn't matter.
let ratio = preferred_aspect_ratio?;
@ -202,6 +190,7 @@ impl IndependentFormattingContext {
let block_size = ratio.compute_dependent_size(Direction::Block, inline_size);
Some(block_size.into())
},
_ => None,
}
}
@ -225,32 +214,6 @@ impl IndependentFormattingContext {
)
}
pub(crate) fn preferred_aspect_ratio(
&self,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> {
match &self.contents {
IndependentFormattingContextContents::NonReplaced(content) => {
content.preferred_aspect_ratio()
},
IndependentFormattingContextContents::Replaced(content) => {
content.preferred_aspect_ratio(self.style(), padding_border_sums)
},
}
}
#[inline]
pub(crate) fn layout_style(&self) -> LayoutStyle {
match &self.contents {
IndependentFormattingContextContents::NonReplaced(content) => {
content.layout_style(&self.base)
},
IndependentFormattingContextContents::Replaced(content) => {
content.layout_style(&self.base)
},
}
}
pub(crate) fn repair_style(
&mut self,
context: &SharedStyleContext,
@ -259,13 +222,83 @@ impl IndependentFormattingContext {
) {
self.base.repair_style(new_style);
match &mut self.contents {
IndependentFormattingContextContents::NonReplaced(content) => {
content.repair_style(context, node, new_style);
},
IndependentFormattingContextContents::Replaced(..) => {},
IndependentFormattingContextContents::Flow(block_formatting_context) => {
block_formatting_context.repair_style(node, new_style);
},
IndependentFormattingContextContents::Flex(flex_container) => {
flex_container.repair_style(new_style)
},
IndependentFormattingContextContents::Grid(taffy_container) => {
taffy_container.repair_style(new_style)
},
IndependentFormattingContextContents::Table(table) => {
table.repair_style(context, new_style)
},
}
}
#[inline]
pub(crate) fn is_table(&self) -> bool {
matches!(
&self.contents,
IndependentFormattingContextContents::Table(_)
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn layout_without_caching(
&self,
layout_context: &LayoutContext,
positioning_context: &mut PositioningContext,
containing_block_for_children: &ContainingBlock,
containing_block: &ContainingBlock,
preferred_aspect_ratio: Option<AspectRatio>,
depends_on_block_constraints: bool,
lazy_block_size: &LazySize,
) -> CacheableLayoutResult {
match &self.contents {
IndependentFormattingContextContents::Replaced(replaced) => replaced.layout(
layout_context,
containing_block_for_children,
preferred_aspect_ratio,
&self.base,
depends_on_block_constraints,
lazy_block_size,
),
IndependentFormattingContextContents::Flow(bfc) => bfc.layout(
layout_context,
positioning_context,
containing_block_for_children,
depends_on_block_constraints,
),
IndependentFormattingContextContents::Flex(fc) => fc.layout(
layout_context,
positioning_context,
containing_block_for_children,
depends_on_block_constraints,
lazy_block_size,
),
IndependentFormattingContextContents::Grid(fc) => fc.layout(
layout_context,
positioning_context,
containing_block_for_children,
containing_block,
),
IndependentFormattingContextContents::Table(table) => table.layout(
layout_context,
positioning_context,
containing_block_for_children,
containing_block,
depends_on_block_constraints,
),
}
}
#[servo_tracing::instrument(
name = "IndependentFormattingContext::layout_with_caching",
skip_all
)]
#[allow(clippy::too_many_arguments)]
pub(crate) fn layout(
&self,
@ -277,94 +310,7 @@ impl IndependentFormattingContext {
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 {
pub(crate) fn layout_without_caching(
&self,
layout_context: &LayoutContext,
positioning_context: &mut PositioningContext,
containing_block_for_children: &ContainingBlock,
containing_block: &ContainingBlock,
depends_on_block_constraints: bool,
lazy_block_size: &LazySize,
) -> CacheableLayoutResult {
match self {
IndependentNonReplacedContents::Flow(bfc) => bfc.layout(
layout_context,
positioning_context,
containing_block_for_children,
depends_on_block_constraints,
),
IndependentNonReplacedContents::Flex(fc) => fc.layout(
layout_context,
positioning_context,
containing_block_for_children,
depends_on_block_constraints,
lazy_block_size,
),
IndependentNonReplacedContents::Grid(fc) => fc.layout(
layout_context,
positioning_context,
containing_block_for_children,
containing_block,
),
IndependentNonReplacedContents::Table(table) => table.layout(
layout_context,
positioning_context,
containing_block_for_children,
containing_block,
depends_on_block_constraints,
),
}
}
#[servo_tracing::instrument(
name = "IndependentNonReplacedContents::layout_with_caching",
skip_all
)]
#[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,
base: &LayoutBoxBase,
depends_on_block_constraints: bool,
lazy_block_size: &LazySize,
) -> CacheableLayoutResult {
if let Some(cache) = base.cached_layout_result.borrow().as_ref() {
if let Some(cache) = self.base.cached_layout_result.borrow().as_ref() {
let cache = &**cache;
if cache.containing_block_for_children_size.inline ==
containing_block_for_children.size.inline &&
@ -390,64 +336,58 @@ impl IndependentNonReplacedContents {
&mut child_positioning_context,
containing_block_for_children,
containing_block,
preferred_aspect_ratio,
depends_on_block_constraints,
lazy_block_size,
);
*base.cached_layout_result.borrow_mut() = Some(Box::new(CacheableLayoutResultAndInputs {
result: result.clone(),
positioning_context: child_positioning_context.clone(),
containing_block_for_children_size: containing_block_for_children.size.clone(),
}));
*self.base.cached_layout_result.borrow_mut() =
Some(Box::new(CacheableLayoutResultAndInputs {
result: result.clone(),
positioning_context: child_positioning_context.clone(),
containing_block_for_children_size: containing_block_for_children.size.clone(),
}));
positioning_context.append(child_positioning_context);
result
}
#[inline]
pub(crate) fn layout_style<'a>(&'a self, base: &'a LayoutBoxBase) -> LayoutStyle<'a> {
match self {
IndependentNonReplacedContents::Flow(fc) => fc.layout_style(base),
IndependentNonReplacedContents::Flex(fc) => fc.layout_style(),
IndependentNonReplacedContents::Grid(fc) => fc.layout_style(),
IndependentNonReplacedContents::Table(fc) => fc.layout_style(None),
pub(crate) fn layout_style(&self) -> LayoutStyle {
match &self.contents {
IndependentFormattingContextContents::Replaced(fc) => fc.layout_style(&self.base),
IndependentFormattingContextContents::Flow(fc) => fc.layout_style(&self.base),
IndependentFormattingContextContents::Flex(fc) => fc.layout_style(),
IndependentFormattingContextContents::Grid(fc) => fc.layout_style(),
IndependentFormattingContextContents::Table(fc) => fc.layout_style(None),
}
}
#[inline]
pub(crate) fn preferred_aspect_ratio(&self) -> Option<AspectRatio> {
// TODO: support preferred aspect ratios on non-replaced boxes.
None
}
fn repair_style(
&mut self,
context: &SharedStyleContext,
node: &ServoLayoutNode,
new_style: &Arc<ComputedValues>,
) {
match self {
IndependentNonReplacedContents::Flow(block_formatting_context) => {
block_formatting_context.repair_style(node, new_style);
pub(crate) fn preferred_aspect_ratio(
&self,
padding_border_sums: &LogicalVec2<Au>,
) -> Option<AspectRatio> {
match &self.contents {
IndependentFormattingContextContents::Replaced(replaced) => {
replaced.preferred_aspect_ratio(self.style(), padding_border_sums)
},
IndependentNonReplacedContents::Flex(flex_container) => {
flex_container.repair_style(new_style)
},
IndependentNonReplacedContents::Grid(taffy_container) => {
taffy_container.repair_style(new_style)
},
IndependentNonReplacedContents::Table(table) => table.repair_style(context, new_style),
// TODO: support preferred aspect ratios on non-replaced boxes.
_ => None,
}
}
}
impl ComputeInlineContentSizes for IndependentNonReplacedContents {
impl ComputeInlineContentSizes for IndependentFormattingContextContents {
fn compute_inline_content_sizes(
&self,
layout_context: &LayoutContext,
constraint_space: &ConstraintSpace,
) -> InlineContentSizesResult {
match self {
Self::Replaced(inner) => {
inner.compute_inline_content_sizes(layout_context, constraint_space)
},
Self::Flow(inner) => inner
.contents
.compute_inline_content_sizes(layout_context, constraint_space),