diff --git a/components/layout/block.rs b/components/layout/block.rs index 4f6bf28004b..2b493d9ee16 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -487,6 +487,7 @@ pub enum BlockType { FloatNonReplaced, InlineBlockReplaced, InlineBlockNonReplaced, + FlexItem, } #[derive(Clone, PartialEq)] @@ -529,7 +530,9 @@ pub struct BlockFlow { bitflags! { flags BlockFlowFlags: u8 { #[doc = "If this is set, then this block flow is the root flow."] - const IS_ROOT = 0x01, + const IS_ROOT = 0b0000_0001, + #[doc = "Whether this block flow is a child of a flex container."] + const IS_FLEX = 0b0001_0000, } } @@ -566,6 +569,8 @@ impl BlockFlow { } else { BlockType::AbsoluteNonReplaced } + } else if self.is_flex() { + BlockType::FlexItem } else if self.base.flags.is_float() { if self.is_replaced_content() { BlockType::FloatReplaced @@ -641,6 +646,12 @@ impl BlockFlow { shared_context, containing_block_inline_size); } + BlockType::FlexItem => { + let inline_size_computer = FlexItem; + inline_size_computer.compute_used_inline_size(self, + shared_context, + containing_block_inline_size); + } } } @@ -1681,6 +1692,14 @@ impl BlockFlow { let padding = self.fragment.style.logical_padding(); padding.block_start.is_definitely_zero() && padding.block_end.is_definitely_zero() } + + pub fn mark_as_flex(&mut self) { + self.flags.insert(IS_FLEX) + } + + pub fn is_flex(&self) -> bool { + self.flags.contains(IS_FLEX) + } } impl Flow for BlockFlow { @@ -2567,6 +2586,7 @@ pub struct FloatNonReplaced; pub struct FloatReplaced; pub struct InlineBlockNonReplaced; pub struct InlineBlockReplaced; +pub struct FlexItem; impl ISizeAndMarginsComputer for AbsoluteNonReplaced { /// Solve the horizontal constraint equation for absolute non-replaced elements. @@ -3057,6 +3077,30 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced { } } +impl ISizeAndMarginsComputer for FlexItem { + // Replace the default method directly to prevent recalculating and setting margins again + // which has already been set by its parent. + fn compute_used_inline_size(&self, + block: &mut BlockFlow, + shared_context: &SharedStyleContext, + parent_flow_inline_size: Au) { + let container_block_size = block.explicit_block_containing_size(shared_context); + block.fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size, + container_block_size); + } + + // Literally do nothing. + fn solve_inline_size_constraints(&self, + block: &mut BlockFlow, + _: &ISizeConstraintInput) + -> ISizeConstraintSolution { + let fragment = block.fragment(); + ISizeConstraintSolution::new(fragment.border_box.size.inline, + fragment.margin.inline_start, + fragment.margin.inline_end) + } +} + /// A stacking context, a pseudo-stacking context, or a non-stacking context. #[derive(Copy, Clone, PartialEq)] pub enum BlockStackingContextType {