layout: Defer some table sizing logic to the parent formatting context (#34889)

A box is usually sized by the formatting context in which it participates.
However, tables have some special sizing behaviors, and these were in
conflict.

Instead of letting tables attempting to re-resolve their inline table,
which failed to e.g. take flex properties into account or resolve sizing
keywords correctly, now tables will trust the inline size determined by
the parent. They will only floor it by the min-content size, and maybe
shrink the final size due to collapsed columns.

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2025-01-08 16:25:58 -08:00 committed by GitHub
parent 1ce6495f0d
commit ceec1759f6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 43 additions and 61 deletions

View file

@ -73,8 +73,8 @@ pub(crate) struct IndependentLayout {
pub content_block_size: Au,
/// The contents of a table may force it to become wider than what we would expect
/// from 'width' and 'min-width'. This is the resulting inline content size,
/// or None for non-table layouts.
/// from 'width' and 'min-width'. It can also become smaller due to collapsed columns.
/// This is the resulting inline content size, or None for non-table layouts.
pub content_inline_size_for_table: Option<Au>,
/// The offset of the last inflow baseline of this layout in the content area, if
@ -182,6 +182,14 @@ impl IndependentFormattingContext {
self.base.base_fragment_info
}
#[inline]
pub(crate) fn is_table(&self) -> bool {
match &self.contents {
IndependentFormattingContextContents::NonReplaced(content) => content.is_table(),
IndependentFormattingContextContents::Replaced(_) => false,
}
}
pub(crate) fn inline_content_sizes(
&self,
layout_context: &LayoutContext,
@ -204,19 +212,13 @@ impl IndependentFormattingContext {
auto_minimum: &LogicalVec2<Au>,
auto_block_size_stretches_to_containing_block: bool,
) -> InlineContentSizesResult {
let is_table = matches!(
self.contents,
IndependentFormattingContextContents::NonReplaced(
IndependentNonReplacedContents::Table(_)
)
);
sizing::outer_inline(
self.style(),
containing_block,
auto_minimum,
auto_block_size_stretches_to_containing_block,
self.is_replaced(),
is_table,
self.is_table(),
true, /* establishes_containing_block */
|padding_border_sums| self.preferred_aspect_ratio(padding_border_sums),
|constraint_space| self.inline_content_sizes(layout_context, constraint_space),
@ -278,6 +280,11 @@ impl IndependentNonReplacedContents {
// TODO: support preferred aspect ratios on non-replaced boxes.
None
}
#[inline]
pub(crate) fn is_table(&self) -> bool {
matches!(self, Self::Table(_))
}
}
impl ComputeInlineContentSizes for IndependentNonReplacedContents {