mirror of
https://github.com/servo/servo.git
synced 2025-07-16 11:53:39 +01:00
layout: Unify layout logic for replaced and non-replaced flex items (#37962)
Laying out a flex item will now use the same logic regardless of whether it's replaced or not. This reduces the amount of code, and should have no observable effect. Testing: Unneeded (no behavior change) This part of #37942 Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
378c4648e4
commit
d5d131c172
1 changed files with 211 additions and 303 deletions
|
@ -27,7 +27,7 @@ use super::geom::{FlexAxis, FlexRelativeRect, FlexRelativeSides, FlexRelativeVec
|
||||||
use super::{FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox};
|
use super::{FlexContainer, FlexContainerConfig, FlexItemBox, FlexLevelBox};
|
||||||
use crate::cell::ArcRefCell;
|
use crate::cell::ArcRefCell;
|
||||||
use crate::context::LayoutContext;
|
use crate::context::LayoutContext;
|
||||||
use crate::formatting_contexts::{Baselines, IndependentFormattingContextContents};
|
use crate::formatting_contexts::Baselines;
|
||||||
use crate::fragment_tree::{
|
use crate::fragment_tree::{
|
||||||
BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, SpecificLayoutInfo,
|
BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags, SpecificLayoutInfo,
|
||||||
};
|
};
|
||||||
|
@ -171,14 +171,6 @@ impl FlexItemLayoutResult {
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compatible_with_containing_block_size_and_content_size(
|
|
||||||
&self,
|
|
||||||
containing_block: &ContainingBlock,
|
|
||||||
size: LogicalVec2<Au>,
|
|
||||||
) -> bool {
|
|
||||||
size == self.content_size && self.compatible_with_containing_block_size(containing_block)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A data structure to hold all of the information about a flex item that has been placed
|
/// A data structure to hold all of the information about a flex item that has been placed
|
||||||
|
@ -1581,7 +1573,8 @@ impl InitialFlexLineLayout<'_> {
|
||||||
// but it would prevent stretching. So we only recognize tables in the inline axis.
|
// but it would prevent stretching. So we only recognize tables in the inline axis.
|
||||||
// The interaction of collapsed table tracks and the flexbox algorithms is unclear,
|
// The interaction of collapsed table tracks and the flexbox algorithms is unclear,
|
||||||
// see https://github.com/w3c/csswg-drafts/issues/11408.
|
// see https://github.com/w3c/csswg-drafts/issues/11408.
|
||||||
item.item.is_table() && axis == Direction::Inline,
|
item.item.box_.independent_formatting_context.is_table() &&
|
||||||
|
axis == Direction::Inline,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
item.layout_result.hypothetical_cross_size
|
item.layout_result.hypothetical_cross_size
|
||||||
|
@ -1756,6 +1749,7 @@ impl FlexItem<'_> {
|
||||||
) -> Option<FlexItemLayoutResult> {
|
) -> Option<FlexItemLayoutResult> {
|
||||||
let containing_block = flex_context.containing_block;
|
let containing_block = flex_context.containing_block;
|
||||||
let independent_formatting_context = &self.box_.independent_formatting_context;
|
let independent_formatting_context = &self.box_.independent_formatting_context;
|
||||||
|
let is_table = independent_formatting_context.is_table();
|
||||||
let mut positioning_context = PositioningContext::default();
|
let mut positioning_context = PositioningContext::default();
|
||||||
let item_writing_mode = independent_formatting_context.style().writing_mode;
|
let item_writing_mode = independent_formatting_context.style().writing_mode;
|
||||||
let item_is_horizontal = item_writing_mode.is_horizontal();
|
let item_is_horizontal = item_writing_mode.is_horizontal();
|
||||||
|
@ -1778,11 +1772,24 @@ impl FlexItem<'_> {
|
||||||
.block
|
.block
|
||||||
.to_definite()
|
.to_definite()
|
||||||
.map(|size| Au::zero().max(size - self.pbm_auto_is_zero.cross));
|
.map(|size| Au::zero().max(size - self.pbm_auto_is_zero.cross));
|
||||||
self.content_cross_sizes.resolve_extrinsic(
|
let tentative_block_content_size = independent_formatting_context
|
||||||
Size::FitContent,
|
.tentative_block_content_size(self.preferred_aspect_ratio);
|
||||||
Au::zero(),
|
if let Some(block_content_size) = tentative_block_content_size {
|
||||||
stretch_size,
|
SizeConstraint::Definite(self.content_cross_sizes.resolve(
|
||||||
)
|
Direction::Block,
|
||||||
|
Size::FitContent,
|
||||||
|
Au::zero,
|
||||||
|
stretch_size,
|
||||||
|
|| block_content_size,
|
||||||
|
is_table,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
self.content_cross_sizes.resolve_extrinsic(
|
||||||
|
Size::FitContent,
|
||||||
|
Au::zero(),
|
||||||
|
stretch_size,
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
(used_main_size, cross_size)
|
(used_main_size, cross_size)
|
||||||
|
@ -1806,7 +1813,7 @@ impl FlexItem<'_> {
|
||||||
Au::zero,
|
Au::zero,
|
||||||
Some(stretch_size),
|
Some(stretch_size),
|
||||||
get_content_size,
|
get_content_size,
|
||||||
self.is_table(),
|
is_table,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
// The main size of a flex item is considered to be definite if its flex basis is definite
|
// The main size of a flex item is considered to be definite if its flex basis is definite
|
||||||
|
@ -1825,191 +1832,118 @@ impl FlexItem<'_> {
|
||||||
(cross_size, main_size)
|
(cross_size, main_size)
|
||||||
};
|
};
|
||||||
|
|
||||||
let container_writing_mode = containing_block.style.writing_mode;
|
|
||||||
let item_style = independent_formatting_context.style();
|
let item_style = independent_formatting_context.style();
|
||||||
match &independent_formatting_context.contents {
|
let item_as_containing_block = ContainingBlock {
|
||||||
IndependentFormattingContextContents::Replaced(replaced) => {
|
size: ContainingBlockSize {
|
||||||
let min_size = flex_axis.vec2_to_flow_relative(FlexRelativeVec2 {
|
inline: inline_size,
|
||||||
main: Size::Numeric(self.content_min_main_size),
|
block: block_size,
|
||||||
cross: self.content_cross_sizes.min,
|
|
||||||
});
|
|
||||||
let max_size = flex_axis.vec2_to_flow_relative(FlexRelativeVec2 {
|
|
||||||
main: self
|
|
||||||
.content_max_main_size
|
|
||||||
.map_or(Size::Initial, Size::Numeric),
|
|
||||||
cross: self.content_cross_sizes.max,
|
|
||||||
});
|
|
||||||
let size = replaced.used_size_as_if_inline_element_from_content_box_sizes(
|
|
||||||
containing_block,
|
|
||||||
item_style,
|
|
||||||
self.preferred_aspect_ratio,
|
|
||||||
LogicalVec2 {
|
|
||||||
block: &Sizes::new(
|
|
||||||
block_size
|
|
||||||
.to_definite()
|
|
||||||
.map_or(Size::Initial, Size::Numeric),
|
|
||||||
min_size.block,
|
|
||||||
max_size.block,
|
|
||||||
),
|
|
||||||
inline: &Sizes::new(
|
|
||||||
Size::Numeric(inline_size),
|
|
||||||
min_size.inline,
|
|
||||||
max_size.inline,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
Size::FitContent.into(),
|
|
||||||
flex_axis.vec2_to_flow_relative(self.pbm_auto_is_zero),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(non_stretch_layout_result) = non_stretch_layout_result {
|
|
||||||
if non_stretch_layout_result
|
|
||||||
.compatible_with_containing_block_size_and_content_size(
|
|
||||||
containing_block,
|
|
||||||
size,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let hypothetical_cross_size = flex_axis.vec2_to_flex_relative(size).cross;
|
|
||||||
let fragments = replaced.make_fragments(
|
|
||||||
flex_context.layout_context,
|
|
||||||
item_style,
|
|
||||||
size.to_physical_size(container_writing_mode),
|
|
||||||
);
|
|
||||||
|
|
||||||
Some(FlexItemLayoutResult {
|
|
||||||
hypothetical_cross_size,
|
|
||||||
fragments,
|
|
||||||
positioning_context,
|
|
||||||
content_size: size,
|
|
||||||
containing_block_inline_size: containing_block.size.inline,
|
|
||||||
containing_block_block_size: containing_block.size.block,
|
|
||||||
depends_on_block_constraints: false,
|
|
||||||
has_child_which_depends_on_block_constraints: false,
|
|
||||||
|
|
||||||
// We will need to synthesize the baseline, but since the used cross
|
|
||||||
// size can differ from the hypothetical cross size, we should defer
|
|
||||||
// synthesizing until needed.
|
|
||||||
baseline_relative_to_margin_box: None,
|
|
||||||
specific_layout_info: None,
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
IndependentFormattingContextContents::NonReplaced(non_replaced) => {
|
style: item_style,
|
||||||
let item_as_containing_block = ContainingBlock {
|
};
|
||||||
size: ContainingBlockSize {
|
|
||||||
inline: inline_size,
|
|
||||||
block: block_size,
|
|
||||||
},
|
|
||||||
style: item_style,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(non_stretch_layout_result) = non_stretch_layout_result {
|
if non_stretch_layout_result.is_some_and(|old_result| {
|
||||||
if non_stretch_layout_result
|
old_result.compatible_with_containing_block_size(&item_as_containing_block)
|
||||||
.compatible_with_containing_block_size(&item_as_containing_block)
|
}) {
|
||||||
{
|
return None;
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let lazy_block_size = if !cross_axis_is_item_block_axis {
|
|
||||||
used_main_size.into()
|
|
||||||
} else if let Some(cross_size) = used_cross_size_override {
|
|
||||||
cross_size.into()
|
|
||||||
} else {
|
|
||||||
// This means that an auto size with stretch alignment will behave different than
|
|
||||||
// a stretch size. That's not what the spec says, but matches other browsers.
|
|
||||||
// To be discussed in https://github.com/w3c/csswg-drafts/issues/11784.
|
|
||||||
let stretch_size = containing_block
|
|
||||||
.size
|
|
||||||
.block
|
|
||||||
.to_definite()
|
|
||||||
.map(|size| Au::zero().max(size - self.pbm_auto_is_zero.cross));
|
|
||||||
LazySize::new(
|
|
||||||
&self.content_cross_sizes,
|
|
||||||
Direction::Block,
|
|
||||||
Size::FitContent,
|
|
||||||
Au::zero,
|
|
||||||
stretch_size,
|
|
||||||
self.is_table(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
let layout = non_replaced.layout(
|
|
||||||
flex_context.layout_context,
|
|
||||||
&mut positioning_context,
|
|
||||||
&item_as_containing_block,
|
|
||||||
containing_block,
|
|
||||||
&independent_formatting_context.base,
|
|
||||||
flex_axis == FlexAxis::Column ||
|
|
||||||
self.cross_size_stretches_to_line ||
|
|
||||||
self.depends_on_block_constraints,
|
|
||||||
&lazy_block_size,
|
|
||||||
);
|
|
||||||
let CacheableLayoutResult {
|
|
||||||
fragments,
|
|
||||||
content_block_size,
|
|
||||||
baselines: content_box_baselines,
|
|
||||||
depends_on_block_constraints,
|
|
||||||
specific_layout_info,
|
|
||||||
..
|
|
||||||
} = layout;
|
|
||||||
|
|
||||||
let has_child_which_depends_on_block_constraints = fragments.iter().any(|fragment| {
|
|
||||||
fragment.base().is_some_and(|base|
|
|
||||||
base.flags.contains(
|
|
||||||
FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM))
|
|
||||||
});
|
|
||||||
|
|
||||||
let hypothetical_cross_size = if cross_axis_is_item_block_axis {
|
|
||||||
lazy_block_size.resolve(|| content_block_size)
|
|
||||||
} else {
|
|
||||||
inline_size
|
|
||||||
};
|
|
||||||
|
|
||||||
let item_writing_mode_is_orthogonal_to_container_writing_mode =
|
|
||||||
flex_context.config.writing_mode.is_horizontal() !=
|
|
||||||
item_style.writing_mode.is_horizontal();
|
|
||||||
let has_compatible_baseline = match flex_axis {
|
|
||||||
FlexAxis::Row => !item_writing_mode_is_orthogonal_to_container_writing_mode,
|
|
||||||
FlexAxis::Column => item_writing_mode_is_orthogonal_to_container_writing_mode,
|
|
||||||
};
|
|
||||||
|
|
||||||
let baselines_relative_to_margin_box = if has_compatible_baseline {
|
|
||||||
content_box_baselines.offset(
|
|
||||||
self.margin.cross_start.auto_is(Au::zero) +
|
|
||||||
self.padding.cross_start +
|
|
||||||
self.border.cross_start,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Baselines::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let baseline_relative_to_margin_box = match self.align_self.0.value() {
|
|
||||||
// ‘baseline’ computes to ‘first baseline’.
|
|
||||||
AlignFlags::BASELINE => baselines_relative_to_margin_box.first,
|
|
||||||
AlignFlags::LAST_BASELINE => baselines_relative_to_margin_box.last,
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(FlexItemLayoutResult {
|
|
||||||
hypothetical_cross_size,
|
|
||||||
fragments,
|
|
||||||
positioning_context,
|
|
||||||
baseline_relative_to_margin_box,
|
|
||||||
content_size: LogicalVec2 {
|
|
||||||
inline: item_as_containing_block.size.inline,
|
|
||||||
block: content_block_size,
|
|
||||||
},
|
|
||||||
containing_block_inline_size: item_as_containing_block.size.inline,
|
|
||||||
containing_block_block_size: item_as_containing_block.size.block,
|
|
||||||
depends_on_block_constraints,
|
|
||||||
has_child_which_depends_on_block_constraints,
|
|
||||||
specific_layout_info,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lazy_block_size = if !cross_axis_is_item_block_axis {
|
||||||
|
used_main_size.into()
|
||||||
|
} else if let Some(cross_size) = used_cross_size_override {
|
||||||
|
cross_size.into()
|
||||||
|
} else {
|
||||||
|
// This means that an auto size with stretch alignment will behave different than
|
||||||
|
// a stretch size. That's not what the spec says, but matches other browsers.
|
||||||
|
// To be discussed in https://github.com/w3c/csswg-drafts/issues/11784.
|
||||||
|
let stretch_size = containing_block
|
||||||
|
.size
|
||||||
|
.block
|
||||||
|
.to_definite()
|
||||||
|
.map(|size| Au::zero().max(size - self.pbm_auto_is_zero.cross));
|
||||||
|
LazySize::new(
|
||||||
|
&self.content_cross_sizes,
|
||||||
|
Direction::Block,
|
||||||
|
Size::FitContent,
|
||||||
|
Au::zero,
|
||||||
|
stretch_size,
|
||||||
|
is_table,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let layout = independent_formatting_context.layout(
|
||||||
|
flex_context.layout_context,
|
||||||
|
&mut positioning_context,
|
||||||
|
&item_as_containing_block,
|
||||||
|
containing_block,
|
||||||
|
self.preferred_aspect_ratio,
|
||||||
|
flex_axis == FlexAxis::Column ||
|
||||||
|
self.cross_size_stretches_to_line ||
|
||||||
|
self.depends_on_block_constraints,
|
||||||
|
&lazy_block_size,
|
||||||
|
);
|
||||||
|
let CacheableLayoutResult {
|
||||||
|
fragments,
|
||||||
|
content_block_size,
|
||||||
|
baselines: content_box_baselines,
|
||||||
|
depends_on_block_constraints,
|
||||||
|
specific_layout_info,
|
||||||
|
..
|
||||||
|
} = layout;
|
||||||
|
|
||||||
|
let has_child_which_depends_on_block_constraints = fragments.iter().any(|fragment| {
|
||||||
|
fragment.base().is_some_and(|base| {
|
||||||
|
base.flags.contains(
|
||||||
|
FragmentFlags::SIZE_DEPENDS_ON_BLOCK_CONSTRAINTS_AND_CAN_BE_CHILD_OF_FLEX_ITEM,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let hypothetical_cross_size = if cross_axis_is_item_block_axis {
|
||||||
|
lazy_block_size.resolve(|| content_block_size)
|
||||||
|
} else {
|
||||||
|
inline_size
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_writing_mode_is_orthogonal_to_container_writing_mode =
|
||||||
|
flex_context.config.writing_mode.is_horizontal() !=
|
||||||
|
item_style.writing_mode.is_horizontal();
|
||||||
|
let has_compatible_baseline = match flex_axis {
|
||||||
|
FlexAxis::Row => !item_writing_mode_is_orthogonal_to_container_writing_mode,
|
||||||
|
FlexAxis::Column => item_writing_mode_is_orthogonal_to_container_writing_mode,
|
||||||
|
};
|
||||||
|
|
||||||
|
let baselines_relative_to_margin_box = if has_compatible_baseline {
|
||||||
|
content_box_baselines.offset(
|
||||||
|
self.margin.cross_start.auto_is(Au::zero) +
|
||||||
|
self.padding.cross_start +
|
||||||
|
self.border.cross_start,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Baselines::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let baseline_relative_to_margin_box = match self.align_self.0.value() {
|
||||||
|
// ‘baseline’ computes to ‘first baseline’.
|
||||||
|
AlignFlags::BASELINE => baselines_relative_to_margin_box.first,
|
||||||
|
AlignFlags::LAST_BASELINE => baselines_relative_to_margin_box.last,
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(FlexItemLayoutResult {
|
||||||
|
hypothetical_cross_size,
|
||||||
|
fragments,
|
||||||
|
positioning_context,
|
||||||
|
baseline_relative_to_margin_box,
|
||||||
|
content_size: LogicalVec2 {
|
||||||
|
inline: item_as_containing_block.size.inline,
|
||||||
|
block: content_block_size,
|
||||||
|
},
|
||||||
|
containing_block_inline_size: item_as_containing_block.size.inline,
|
||||||
|
containing_block_block_size: item_as_containing_block.size.block,
|
||||||
|
depends_on_block_constraints,
|
||||||
|
has_child_which_depends_on_block_constraints,
|
||||||
|
specific_layout_info,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn synthesized_baseline_relative_to_margin_box(&self, content_size: Au) -> Au {
|
fn synthesized_baseline_relative_to_margin_box(&self, content_size: Au) -> Au {
|
||||||
|
@ -2143,11 +2077,6 @@ impl FlexItem<'_> {
|
||||||
};
|
};
|
||||||
outer_cross_start + margin.cross_start + self.border.cross_start + self.padding.cross_start
|
outer_cross_start + margin.cross_start + self.border.cross_start + self.padding.cross_start
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_table(&self) -> bool {
|
|
||||||
self.box_.independent_formatting_context.is_table()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlexItemBox {
|
impl FlexItemBox {
|
||||||
|
@ -2612,109 +2541,88 @@ impl FlexItemBox {
|
||||||
cross_size_stretches_to_container_size: bool,
|
cross_size_stretches_to_container_size: bool,
|
||||||
intrinsic_sizing_mode: IntrinsicSizingMode,
|
intrinsic_sizing_mode: IntrinsicSizingMode,
|
||||||
) -> Au {
|
) -> Au {
|
||||||
let mut positioning_context = PositioningContext::default();
|
let content_block_size = || {
|
||||||
let style = self.independent_formatting_context.style();
|
let mut positioning_context = PositioningContext::default();
|
||||||
match &self.independent_formatting_context.contents {
|
let style = self.independent_formatting_context.style();
|
||||||
IndependentFormattingContextContents::Replaced(replaced) => {
|
|
||||||
let get_used_size = |block_sizes| {
|
// We are computing the intrinsic block size, so the tentative block size that we use
|
||||||
replaced.used_size_as_if_inline_element_from_content_box_sizes(
|
// as an input to the intrinsic inline sizes needs to ignore the values of the sizing
|
||||||
flex_context.containing_block,
|
// properties in the block axis.
|
||||||
style,
|
let tentative_block_size = SizeConstraint::default();
|
||||||
preferred_aspect_ratio,
|
|
||||||
LogicalVec2 {
|
// TODO: This is wrong if the item writing mode is different from the flex
|
||||||
block: block_sizes,
|
// container's writing mode.
|
||||||
inline: &content_box_sizes.inline,
|
let inline_size = {
|
||||||
},
|
let initial_behavior = if cross_size_stretches_to_container_size {
|
||||||
Size::FitContent.into(),
|
Size::Stretch
|
||||||
LogicalVec2 {
|
|
||||||
inline: pbm_auto_is_zero.cross,
|
|
||||||
block: pbm_auto_is_zero.main,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if intrinsic_sizing_mode == IntrinsicSizingMode::Size {
|
|
||||||
get_used_size(&Sizes::default()).block
|
|
||||||
} else {
|
} else {
|
||||||
get_used_size(&content_box_sizes.block).block
|
Size::FitContent
|
||||||
}
|
};
|
||||||
},
|
let stretch_size =
|
||||||
IndependentFormattingContextContents::NonReplaced(non_replaced) => {
|
flex_context.containing_block.size.inline - pbm_auto_is_zero.cross;
|
||||||
// TODO: This is wrong if the item writing mode is different from the flex
|
let get_content_size = || {
|
||||||
// container's writing mode.
|
let constraint_space = ConstraintSpace::new(
|
||||||
let inline_size = {
|
tentative_block_size,
|
||||||
let initial_behavior = if cross_size_stretches_to_container_size {
|
style.writing_mode,
|
||||||
Size::Stretch
|
preferred_aspect_ratio,
|
||||||
} else {
|
);
|
||||||
Size::FitContent
|
self.independent_formatting_context
|
||||||
};
|
.inline_content_sizes(flex_context.layout_context, &constraint_space)
|
||||||
let stretch_size =
|
.sizes
|
||||||
flex_context.containing_block.size.inline - pbm_auto_is_zero.cross;
|
};
|
||||||
let get_content_size = || {
|
content_box_sizes.inline.resolve(
|
||||||
let constraint_space = ConstraintSpace::new(
|
Direction::Inline,
|
||||||
SizeConstraint::default(),
|
initial_behavior,
|
||||||
style.writing_mode,
|
Au::zero,
|
||||||
non_replaced.preferred_aspect_ratio(),
|
Some(stretch_size),
|
||||||
);
|
get_content_size,
|
||||||
self.independent_formatting_context
|
false,
|
||||||
.inline_content_sizes(flex_context.layout_context, &constraint_space)
|
)
|
||||||
.sizes
|
};
|
||||||
};
|
let item_as_containing_block = ContainingBlock {
|
||||||
content_box_sizes.inline.resolve(
|
size: ContainingBlockSize {
|
||||||
Direction::Inline,
|
inline: inline_size,
|
||||||
initial_behavior,
|
block: tentative_block_size,
|
||||||
Au::zero,
|
},
|
||||||
Some(stretch_size),
|
style,
|
||||||
get_content_size,
|
};
|
||||||
false,
|
self.independent_formatting_context
|
||||||
)
|
.layout(
|
||||||
};
|
flex_context.layout_context,
|
||||||
let item_as_containing_block = ContainingBlock {
|
&mut positioning_context,
|
||||||
size: ContainingBlockSize {
|
&item_as_containing_block,
|
||||||
inline: inline_size,
|
flex_context.containing_block,
|
||||||
block: SizeConstraint::default(),
|
preferred_aspect_ratio,
|
||||||
},
|
false, /* depends_on_block_constraints */
|
||||||
style,
|
&LazySize::intrinsic(),
|
||||||
};
|
)
|
||||||
let mut content_block_size = || {
|
.content_block_size
|
||||||
non_replaced
|
};
|
||||||
.layout(
|
match intrinsic_sizing_mode {
|
||||||
flex_context.layout_context,
|
IntrinsicSizingMode::Contribution => {
|
||||||
&mut positioning_context,
|
let stretch_size = flex_context
|
||||||
&item_as_containing_block,
|
.containing_block
|
||||||
flex_context.containing_block,
|
.size
|
||||||
&self.independent_formatting_context.base,
|
.block
|
||||||
false, /* depends_on_block_constraints */
|
.to_definite()
|
||||||
&LazySize::intrinsic(),
|
.map(|block_size| block_size - pbm_auto_is_zero.main);
|
||||||
)
|
let inner_block_size = content_box_sizes.block.resolve(
|
||||||
.content_block_size
|
Direction::Block,
|
||||||
};
|
Size::FitContent,
|
||||||
match intrinsic_sizing_mode {
|
Au::zero,
|
||||||
IntrinsicSizingMode::Contribution => {
|
stretch_size,
|
||||||
let stretch_size = flex_context
|
|| ContentSizes::from(content_block_size()),
|
||||||
.containing_block
|
// Tables have a special sizing in the block axis that handles collapsed rows
|
||||||
.size
|
// by ignoring the sizing properties and instead relying on the content block size,
|
||||||
.block
|
// which should indirectly take sizing properties into account.
|
||||||
.to_definite()
|
// However, above we laid out the table with a SizeConstraint::default() block size,
|
||||||
.map(|block_size| block_size - pbm_auto_is_zero.main);
|
// so the content block size doesn't take sizing properties into account.
|
||||||
let inner_block_size = content_box_sizes.block.resolve(
|
// Therefore, pretending that it's never a table tends to provide a better result.
|
||||||
Direction::Block,
|
false, /* is_table */
|
||||||
Size::FitContent,
|
);
|
||||||
Au::zero,
|
inner_block_size + pbm_auto_is_zero.main
|
||||||
stretch_size,
|
|
||||||
|| ContentSizes::from(content_block_size()),
|
|
||||||
// Tables have a special sizing in the block axis that handles collapsed rows
|
|
||||||
// by ignoring the sizing properties and instead relying on the content block size,
|
|
||||||
// which should indirectly take sizing properties into account.
|
|
||||||
// However, above we laid out the table with a SizeConstraint::default() block size,
|
|
||||||
// so the content block size doesn't take sizing properties into account.
|
|
||||||
// Therefore, pretending that it's never a table tends to provide a better result.
|
|
||||||
false, /* is_table */
|
|
||||||
);
|
|
||||||
inner_block_size + pbm_auto_is_zero.main
|
|
||||||
},
|
|
||||||
IntrinsicSizingMode::Size => content_block_size(),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
IntrinsicSizingMode::Size => content_block_size(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue