Make the width of block customizable by its parent

Add a 'IS_FLEX' flag to bitflags of block flow, and when it is set, the
block will use the inline size and margins set by its parent.
This commit is contained in:
Pu Xingyu 2016-07-20 22:42:02 +08:00
parent 05cf52cb0b
commit bc8d22a5e7

View file

@ -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 {