mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Refactor assign_height and assign_width for block flow.
This commit is contained in:
parent
3401a568f2
commit
8dbec50178
1 changed files with 274 additions and 180 deletions
|
@ -625,47 +625,38 @@ impl BlockFlow {
|
|||
self.base.fixed_descendants.static_y_offsets = fixed_descendant_y_offsets;
|
||||
}
|
||||
|
||||
/// Assign height for current flow.
|
||||
///
|
||||
/// + Collapse margins for flow's children and set in-flow child flows'
|
||||
/// y-coordinates now that we know their heights.
|
||||
/// + Calculate and set the height of the current flow.
|
||||
/// + Calculate height, vertical margins, and y-coordinate for the flow's
|
||||
/// box. Ideally, this should be calculated using CSS Section 10.6.7
|
||||
///
|
||||
/// For absolute flows, store the calculated content height for the flow.
|
||||
/// Defer the calculation of the other values till a later traversal.
|
||||
///
|
||||
/// inline(always) because this is only ever called by in-order or non-in-order top-level
|
||||
/// methods
|
||||
#[inline(always)]
|
||||
fn assign_height_block_base(&mut self, ctx: &mut LayoutContext, inorder: bool) {
|
||||
let mut cur_y = Au::new(0);
|
||||
let mut clearance = Au::new(0);
|
||||
// Offset to content edge of box_
|
||||
let mut top_offset = Au::new(0);
|
||||
let mut bottom_offset = Au::new(0);
|
||||
let mut left_offset = Au::new(0);
|
||||
|
||||
for box_ in self.box_.iter() {
|
||||
// Note: Ignoring clearance for absolute flows as of now.
|
||||
if !self.is_absolutely_positioned() {
|
||||
clearance = match box_.clear() {
|
||||
None => Au::new(0),
|
||||
Some(clear) => {
|
||||
self.base.floats.clearance(clear)
|
||||
}
|
||||
/// Calculate clearance, top_offset, bottom_offset, and left_offset for the box.
|
||||
/// If `ignore_clear` is true, clearance does not need to be calculated.
|
||||
pub fn initialize_offsets(&mut self, ignore_clear: bool) -> (Au, Au, Au, Au) {
|
||||
match self.box_ {
|
||||
None => (Au(0), Au(0), Au(0), Au(0)),
|
||||
Some(ref box_) => {
|
||||
let clearance = match box_.clear() {
|
||||
Some(clear) if !ignore_clear => self.base.floats.clearance(clear),
|
||||
_ => Au::new(0)
|
||||
};
|
||||
}
|
||||
|
||||
top_offset = clearance + box_.margin.get().top + box_.border.get().top +
|
||||
// Offset to content edge of box_
|
||||
let top_offset = clearance + box_.margin.get().top + box_.border.get().top +
|
||||
box_.padding.get().top;
|
||||
cur_y = cur_y + top_offset;
|
||||
bottom_offset = box_.margin.get().bottom + box_.border.get().bottom +
|
||||
let bottom_offset = box_.margin.get().bottom + box_.border.get().bottom +
|
||||
box_.padding.get().bottom;
|
||||
left_offset = box_.offset();
|
||||
let left_offset = box_.offset();
|
||||
|
||||
(clearance, top_offset, bottom_offset, left_offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// In case of inorder assign_height traversal and not absolute flow,
|
||||
/// 'assign_height's of all children are visited
|
||||
/// and Float info is shared between adjacent children.
|
||||
/// Float info of the last child is saved in parent flow.
|
||||
pub fn handle_children_floats_if_necessary(&mut self,
|
||||
ctx: &mut LayoutContext,
|
||||
inorder: bool,
|
||||
left_offset: Au,
|
||||
top_offset: Au) {
|
||||
// Note: Ignoring floats for absolute flow as of now.
|
||||
if inorder && !self.is_absolutely_positioned() {
|
||||
// Floats for blocks work like this:
|
||||
|
@ -684,9 +675,41 @@ impl BlockFlow {
|
|||
}
|
||||
self.base.floats = floats;
|
||||
}
|
||||
}
|
||||
|
||||
// The amount of margin that we can potentially collapse with
|
||||
let mut collapsible = Au::new(0);
|
||||
/// Compute margin_top and margin_bottom. Also, it is decided whether top margin and
|
||||
/// bottom margin are collapsible according to CSS 2.1 § 8.3.1.
|
||||
pub fn precompute_margin(&mut self) -> (Au, Au, bool, bool) {
|
||||
match self.box_ {
|
||||
// Margins for an absolutely positioned element do not collapse with
|
||||
// its children.
|
||||
Some(ref box_) if !self.is_absolutely_positioned() => {
|
||||
let top_margin_collapsible = !self.is_root &&
|
||||
box_.border.get().top == Au(0) &&
|
||||
box_.padding.get().top == Au(0);
|
||||
|
||||
let bottom_margin_collapsible = !self.is_root &&
|
||||
box_.border.get().bottom == Au(0) &&
|
||||
box_.padding.get().bottom == Au(0);
|
||||
|
||||
let margin_top = box_.margin.get().top;
|
||||
let margin_bottom = box_.margin.get().bottom;
|
||||
|
||||
(margin_top, margin_bottom, top_margin_collapsible, bottom_margin_collapsible)
|
||||
},
|
||||
_ => (Au(0), Au(0), false, false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute collapsed margins between adjacent children or between the first/last child and parent
|
||||
/// according to CSS 2.1 § 8.3.1. Current y position(cur_y) is continually updated for collapsing result.
|
||||
pub fn compute_margin_collapse(&mut self,
|
||||
cur_y: &mut Au,
|
||||
top_offset: &mut Au,
|
||||
margin_top: &mut Au,
|
||||
margin_bottom: &mut Au,
|
||||
top_margin_collapsible: bool,
|
||||
bottom_margin_collapsible: bool) -> Au {
|
||||
// How much to move up by to get to the beginning of
|
||||
// current kid flow.
|
||||
// Example: if previous sibling's margin-bottom is 20px and your
|
||||
|
@ -694,55 +717,38 @@ impl BlockFlow {
|
|||
// will be at the bottom margin edge of the previous sibling, we have
|
||||
// to move up by 12px to get to our top margin edge. So, `collapsing`
|
||||
// will be set to 12px
|
||||
let mut collapsing = Au::new(0);
|
||||
let mut margin_top = Au::new(0);
|
||||
let mut margin_bottom = Au::new(0);
|
||||
let mut top_margin_collapsible = false;
|
||||
let mut bottom_margin_collapsible = false;
|
||||
let mut first_in_flow = true;
|
||||
// Margins for an absolutely positioned element do not collapse with
|
||||
// its children.
|
||||
if !self.is_absolutely_positioned() {
|
||||
for box_ in self.box_.iter() {
|
||||
if !self.is_root() && box_.border.get().top == Au(0)
|
||||
&& box_.padding.get().top == Au(0) {
|
||||
|
||||
collapsible = box_.margin.get().top;
|
||||
top_margin_collapsible = true;
|
||||
}
|
||||
if !self.is_root() && box_.border.get().bottom == Au(0) &&
|
||||
box_.padding.get().bottom == Au(0) {
|
||||
bottom_margin_collapsible = true;
|
||||
}
|
||||
margin_top = box_.margin.get().top;
|
||||
margin_bottom = box_.margin.get().bottom;
|
||||
}
|
||||
}
|
||||
let mut collapsing = Au::new(0);
|
||||
// The amount of margin that we can potentially collapse with
|
||||
let mut collapsible = if top_margin_collapsible {
|
||||
*margin_top
|
||||
} else {
|
||||
Au(0)
|
||||
};
|
||||
|
||||
// At this point, cur_y is at the content edge of the flow's box_
|
||||
for kid in self.base.child_iter() {
|
||||
// At this point, cur_y is at bottom margin edge of previous kid
|
||||
|
||||
if kid.is_absolutely_positioned() {
|
||||
// Assume that the `hypothetical box` for an absolute flow
|
||||
// starts immediately after the bottom margin edge of the
|
||||
// previous flow.
|
||||
kid.as_block().base.position.origin.y = cur_y;
|
||||
kid.as_block().base.position.origin.y = *cur_y;
|
||||
// Skip the collapsing for absolute flow kids and continue
|
||||
// with the next flow.
|
||||
} else {
|
||||
kid.collapse_margins(top_margin_collapsible,
|
||||
&mut first_in_flow,
|
||||
&mut margin_top,
|
||||
&mut top_offset,
|
||||
margin_top,
|
||||
top_offset,
|
||||
&mut collapsing,
|
||||
&mut collapsible);
|
||||
let child_node = flow::mut_base(kid);
|
||||
cur_y = cur_y - collapsing;
|
||||
*cur_y = *cur_y - collapsing;
|
||||
// At this point, after moving up by `collapsing`, cur_y is at the
|
||||
// top margin edge of kid
|
||||
child_node.position.origin.y = cur_y;
|
||||
cur_y = cur_y + child_node.position.size.height;
|
||||
child_node.position.origin.y = *cur_y;
|
||||
*cur_y = *cur_y + child_node.position.size.height;
|
||||
// At this point, cur_y is at the bottom margin edge of kid
|
||||
}
|
||||
}
|
||||
|
@ -754,14 +760,128 @@ impl BlockFlow {
|
|||
// The bottom margin for an absolutely positioned element does not
|
||||
// collapse even with its children.
|
||||
collapsing = if bottom_margin_collapsible && !self.is_absolutely_positioned() {
|
||||
if margin_bottom < collapsible {
|
||||
margin_bottom = collapsible;
|
||||
if *margin_bottom < collapsible {
|
||||
*margin_bottom = collapsible;
|
||||
}
|
||||
collapsible
|
||||
} else {
|
||||
Au::new(0)
|
||||
};
|
||||
|
||||
collapsing
|
||||
}
|
||||
|
||||
/// For an absolutely positioned element, store the content height for use in calculating
|
||||
/// the absolute flow's dimensions later.
|
||||
pub fn store_content_height_if_absolutely_positioned(&mut self,
|
||||
height: Au) -> bool {
|
||||
if self.is_absolutely_positioned() {
|
||||
for box_ in self.box_.iter() {
|
||||
let mut temp_position = box_.border_box.get();
|
||||
temp_position.size.height = height;
|
||||
box_.border_box.set(temp_position);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Compute the box height and set border_box and margin of the box.
|
||||
pub fn compute_height_position(&mut self,
|
||||
height: &mut Au,
|
||||
border_and_padding: Au,
|
||||
margin_top: Au,
|
||||
margin_bottom: Au,
|
||||
clearance: Au) {
|
||||
// Here, height is content height of box_
|
||||
let mut noncontent_height = border_and_padding;
|
||||
for box_ in self.box_.iter() {
|
||||
let mut position = box_.border_box.get();
|
||||
let mut margin = box_.margin.get();
|
||||
|
||||
// The associated box is the border box of this flow.
|
||||
// Margin after collapse
|
||||
margin.top = margin_top;
|
||||
margin.bottom = margin_bottom;
|
||||
|
||||
position.origin.y = clearance + margin.top;
|
||||
// Border box height
|
||||
position.size.height = *height + noncontent_height;
|
||||
|
||||
noncontent_height = noncontent_height + clearance + margin.top + margin.bottom;
|
||||
|
||||
box_.border_box.set(position);
|
||||
box_.margin.set(margin);
|
||||
}
|
||||
|
||||
// Height of margin box + clearance
|
||||
self.base.position.size.height = *height + noncontent_height;
|
||||
}
|
||||
|
||||
/// Set floats_out at the last step of the assign height calculation.
|
||||
pub fn set_floats_out_if_inorder(&mut self,
|
||||
inorder: bool,
|
||||
height: Au,
|
||||
cur_y: Au,
|
||||
top_offset: Au,
|
||||
bottom_offset: Au,
|
||||
left_offset: Au) {
|
||||
if inorder {
|
||||
let extra_height = height - (cur_y - top_offset) + bottom_offset;
|
||||
self.base.floats.translate(Point2D(left_offset, -extra_height));
|
||||
}
|
||||
}
|
||||
|
||||
/// Assign heights for all flows in absolute flow tree and store overflow for all
|
||||
/// absolute descendants.
|
||||
pub fn assign_height_absolute_flows(&mut self, ctx: &mut LayoutContext) {
|
||||
if self.is_root_of_absolute_flow_tree() {
|
||||
// Assign heights for all flows in this Absolute flow tree.
|
||||
// This is preorder because the height of an absolute flow may depend on
|
||||
// the height of its CB, which may also be an absolute flow.
|
||||
self.traverse_preorder_absolute_flows(&mut AbsoluteAssignHeightsTraversal(ctx));
|
||||
// Store overflow for all absolute descendants.
|
||||
self.traverse_postorder_absolute_flows(&mut AbsoluteStoreOverflowTraversal {
|
||||
layout_context: ctx,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Assign height for current flow.
|
||||
///
|
||||
/// + Collapse margins for flow's children and set in-flow child flows'
|
||||
/// y-coordinates now that we know their heights.
|
||||
/// + Calculate and set the height of the current flow.
|
||||
/// + Calculate height, vertical margins, and y-coordinate for the flow's
|
||||
/// box. Ideally, this should be calculated using CSS Section 10.6.7
|
||||
///
|
||||
/// For absolute flows, store the calculated content height for the flow.
|
||||
/// Defer the calculation of the other values till a later traversal.
|
||||
///
|
||||
/// inline(always) because this is only ever called by in-order or non-in-order top-level
|
||||
/// methods
|
||||
#[inline(always)]
|
||||
fn assign_height_block_base(&mut self, ctx: &mut LayoutContext, inorder: bool) {
|
||||
|
||||
// Note: Ignoring clearance for absolute flows as of now.
|
||||
let ignore_clear = self.is_absolutely_positioned();
|
||||
let (clearance, mut top_offset, bottom_offset, left_offset) =
|
||||
self.initialize_offsets(ignore_clear);
|
||||
|
||||
self.handle_children_floats_if_necessary(ctx, inorder,
|
||||
left_offset, top_offset);
|
||||
|
||||
let (mut margin_top, mut margin_bottom,
|
||||
top_margin_collapsible, bottom_margin_collapsible) = self.precompute_margin();
|
||||
|
||||
let mut cur_y = top_offset;
|
||||
let collapsing = self.compute_margin_collapse(&mut cur_y,
|
||||
&mut top_offset,
|
||||
&mut margin_top,
|
||||
&mut margin_bottom,
|
||||
top_margin_collapsible,
|
||||
bottom_margin_collapsible);
|
||||
|
||||
// TODO: A box's own margins collapse if the 'min-height' property is zero, and it has neither
|
||||
// top or bottom borders nor top or bottom padding, and it has a 'height' of either 0 or 'auto',
|
||||
// and it does not contain a line box, and all of its in-flow children's margins (if any) collapse.
|
||||
|
@ -782,17 +902,12 @@ impl BlockFlow {
|
|||
cur_y - top_offset - collapsing
|
||||
};
|
||||
|
||||
if self.is_absolutely_positioned() {
|
||||
// Store the content height for use in calculating the absolute
|
||||
// flow's dimensions later.
|
||||
for box_ in self.box_.iter() {
|
||||
let mut temp_position = box_.border_box.get();
|
||||
temp_position.size.height = height;
|
||||
box_.border_box.set(temp_position);
|
||||
}
|
||||
// For an absolutely positioned element, store the content height and stop the function.
|
||||
if self.store_content_height_if_absolutely_positioned(height) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut border_and_padding = Au::new(0);
|
||||
for box_ in self.box_.iter() {
|
||||
let style = box_.style();
|
||||
|
||||
|
@ -803,51 +918,19 @@ impl BlockFlow {
|
|||
Auto => height,
|
||||
Specified(value) => value
|
||||
};
|
||||
}
|
||||
|
||||
// Here, height is content height of box_
|
||||
|
||||
let mut noncontent_height = Au::new(0);
|
||||
for box_ in self.box_.iter() {
|
||||
let mut position = box_.border_box.get();
|
||||
let mut margin = box_.margin.get();
|
||||
|
||||
// The associated box is the border box of this flow.
|
||||
// Margin after collapse
|
||||
margin.top = margin_top;
|
||||
margin.bottom = margin_bottom;
|
||||
|
||||
noncontent_height = box_.padding.get().top + box_.padding.get().bottom +
|
||||
border_and_padding = box_.padding.get().top + box_.padding.get().bottom +
|
||||
box_.border.get().top + box_.border.get().bottom;
|
||||
|
||||
position.origin.y = clearance + margin.top;
|
||||
// Border box height
|
||||
position.size.height = height + noncontent_height;
|
||||
|
||||
noncontent_height = noncontent_height + clearance + margin.top + margin.bottom;
|
||||
|
||||
box_.border_box.set(position);
|
||||
box_.margin.set(margin);
|
||||
}
|
||||
|
||||
// Height of margin box + clearance
|
||||
self.base.position.size.height = height + noncontent_height;
|
||||
self.compute_height_position(&mut height,
|
||||
border_and_padding,
|
||||
margin_top,
|
||||
margin_bottom,
|
||||
clearance);
|
||||
|
||||
if inorder {
|
||||
let extra_height = height - (cur_y - top_offset) + bottom_offset;
|
||||
self.base.floats.translate(Point2D(left_offset, -extra_height));
|
||||
}
|
||||
|
||||
if self.is_root_of_absolute_flow_tree() {
|
||||
// Assign heights for all flows in this Absolute flow tree.
|
||||
// This is preorder because the height of an absolute flow may depend on
|
||||
// the height of its CB, which may also be an absolute flow.
|
||||
self.traverse_preorder_absolute_flows(&mut AbsoluteAssignHeightsTraversal(ctx));
|
||||
// Store overflow for all absolute descendants.
|
||||
self.traverse_postorder_absolute_flows(&mut AbsoluteStoreOverflowTraversal {
|
||||
layout_context: ctx,
|
||||
});
|
||||
}
|
||||
self.set_floats_out_if_inorder(inorder, height, cur_y, top_offset, bottom_offset, left_offset);
|
||||
self.assign_height_absolute_flows(ctx);
|
||||
if self.is_root() {
|
||||
self.assign_height_store_overflow_fixed_flows(ctx);
|
||||
}
|
||||
|
@ -990,6 +1073,74 @@ impl BlockFlow {
|
|||
box_.border_box.set(position);
|
||||
}
|
||||
|
||||
/// In case of float, initialize containing_width at the beginning step of assign_width.
|
||||
pub fn set_containing_width_if_float(&mut self, containing_block_width: Au) {
|
||||
if self.is_float() {
|
||||
self.float.get_mut_ref().containing_width = containing_block_width;
|
||||
|
||||
// Parent usually sets this, but floats are never inorder
|
||||
self.base.flags_info.flags.set_inorder(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// Assign the computed left_content_edge and content_width to children.
|
||||
pub fn propagate_assigned_width_to_children(&mut self, left_content_edge: Au,
|
||||
content_width: Au) {
|
||||
let has_inorder_children = if self.is_float() {
|
||||
self.base.num_floats > 0
|
||||
} else {
|
||||
self.base.flags_info.flags.inorder() || self.base.num_floats > 0
|
||||
};
|
||||
|
||||
let kid_abs_cb_x_offset;
|
||||
if self.is_positioned() {
|
||||
match self.box_ {
|
||||
Some(ref box_) => {
|
||||
// Pass yourself as a new Containing Block
|
||||
// The static x offset for any immediate kid flows will be the
|
||||
// left padding
|
||||
kid_abs_cb_x_offset = box_.padding.get().left;
|
||||
}
|
||||
None => fail!("BlockFlow: no principal box found"),
|
||||
}
|
||||
} else {
|
||||
// For kids, the left margin edge will be at our left content edge.
|
||||
// The current static offset is at our left margin
|
||||
// edge. So move in to the left content edge.
|
||||
kid_abs_cb_x_offset = self.base.absolute_static_x_offset + left_content_edge;
|
||||
}
|
||||
let kid_fixed_cb_x_offset = self.base.fixed_static_x_offset + left_content_edge;
|
||||
|
||||
// FIXME(ksh8281): avoid copy
|
||||
let flags_info = self.base.flags_info.clone();
|
||||
for kid in self.base.child_iter() {
|
||||
assert!(kid.is_block_flow() || kid.is_inline_flow());
|
||||
|
||||
if kid.is_block_flow() {
|
||||
let kid_block = kid.as_block();
|
||||
kid_block.base.absolute_static_x_offset = kid_abs_cb_x_offset;
|
||||
kid_block.base.fixed_static_x_offset = kid_fixed_cb_x_offset;
|
||||
}
|
||||
let child_base = flow::mut_base(kid);
|
||||
// Left margin edge of kid flow is at our left content edge
|
||||
child_base.position.origin.x = left_content_edge;
|
||||
// Width of kid flow is our content width
|
||||
child_base.position.size.width = content_width;
|
||||
child_base.flags_info.flags.set_inorder(has_inorder_children);
|
||||
|
||||
if !child_base.flags_info.flags.inorder() {
|
||||
child_base.floats = Floats::new();
|
||||
}
|
||||
|
||||
// Per CSS 2.1 § 16.3.1, text decoration propagates to all children in flow.
|
||||
//
|
||||
// TODO(pcwalton): When we have out-of-flow children, don't unconditionally propagate.
|
||||
|
||||
child_base.flags_info.propagate_text_decoration_from_parent(&flags_info);
|
||||
child_base.flags_info.propagate_text_alignment_from_parent(&flags_info)
|
||||
}
|
||||
}
|
||||
|
||||
/// Add display items for current block.
|
||||
///
|
||||
/// Set the absolute position for children after doing any offsetting for
|
||||
|
@ -1323,12 +1474,7 @@ impl Flow for BlockFlow {
|
|||
let mut left_content_edge = Au::new(0);
|
||||
let mut content_width = containing_block_width;
|
||||
|
||||
if self.is_float() {
|
||||
self.float.get_mut_ref().containing_width = containing_block_width;
|
||||
|
||||
// Parent usually sets this, but floats are never inorder
|
||||
self.base.flags_info.flags.set_inorder(false);
|
||||
}
|
||||
self.set_containing_width_if_float(containing_block_width);
|
||||
|
||||
self.compute_used_width(ctx, containing_block_width);
|
||||
|
||||
|
@ -1345,59 +1491,7 @@ impl Flow for BlockFlow {
|
|||
self.base.position.size.width = content_width;
|
||||
}
|
||||
|
||||
let has_inorder_children = if self.is_float() {
|
||||
self.base.num_floats > 0
|
||||
} else {
|
||||
self.base.flags_info.flags.inorder() || self.base.num_floats > 0
|
||||
};
|
||||
|
||||
let kid_abs_cb_x_offset;
|
||||
if self.is_positioned() {
|
||||
match self.box_ {
|
||||
Some(ref box_) => {
|
||||
// Pass yourself as a new Containing Block
|
||||
// The static x offset for any immediate kid flows will be the
|
||||
// left padding
|
||||
kid_abs_cb_x_offset = box_.padding.get().left;
|
||||
}
|
||||
None => fail!("BlockFlow: no principal box found"),
|
||||
}
|
||||
} else {
|
||||
// For kids, the left margin edge will be at our left content edge.
|
||||
// The current static offset is at our left margin
|
||||
// edge. So move in to the left content edge.
|
||||
kid_abs_cb_x_offset = self.base.absolute_static_x_offset + left_content_edge;
|
||||
}
|
||||
let kid_fixed_cb_x_offset = self.base.fixed_static_x_offset + left_content_edge;
|
||||
|
||||
// FIXME(ksh8281): avoid copy
|
||||
let flags_info = self.base.flags_info.clone();
|
||||
for kid in self.base.child_iter() {
|
||||
assert!(kid.is_block_flow() || kid.is_inline_flow());
|
||||
|
||||
if kid.is_block_flow() {
|
||||
let kid_block = kid.as_block();
|
||||
kid_block.base.absolute_static_x_offset = kid_abs_cb_x_offset;
|
||||
kid_block.base.fixed_static_x_offset = kid_fixed_cb_x_offset;
|
||||
}
|
||||
let child_base = flow::mut_base(kid);
|
||||
// Left margin edge of kid flow is at our left content edge
|
||||
child_base.position.origin.x = left_content_edge;
|
||||
// Width of kid flow is our content width
|
||||
child_base.position.size.width = content_width;
|
||||
child_base.flags_info.flags.set_inorder(has_inorder_children);
|
||||
|
||||
if !child_base.flags_info.flags.inorder() {
|
||||
child_base.floats = Floats::new();
|
||||
}
|
||||
|
||||
// Per CSS 2.1 § 16.3.1, text decoration propagates to all children in flow.
|
||||
//
|
||||
// TODO(pcwalton): When we have out-of-flow children, don't unconditionally propagate.
|
||||
|
||||
child_base.flags_info.propagate_text_decoration_from_parent(&flags_info);
|
||||
child_base.flags_info.propagate_text_alignment_from_parent(&flags_info)
|
||||
}
|
||||
self.propagate_assigned_width_to_children(left_content_edge, content_width);
|
||||
}
|
||||
|
||||
/// This is called on kid flows by a parent.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue