mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
layout: Incrementalize reflow of block formatting contexts impacted by
floats, and make float placement idempotent. This moves float placement outside sequential block size computation. Improves the maze solver.
This commit is contained in:
parent
be36fcd3b1
commit
55da2c97d5
11 changed files with 157 additions and 48 deletions
|
@ -32,8 +32,9 @@ use context::LayoutContext;
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
use display_list_builder::{BlockFlowDisplayListBuilding, BlockLevel, FragmentDisplayListBuilding};
|
use display_list_builder::{BlockFlowDisplayListBuilding, BlockLevel, FragmentDisplayListBuilding};
|
||||||
use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo};
|
use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo};
|
||||||
use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FlowClass, Flow, ImmutableFlowUtils};
|
use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FloatIfNecessary, FlowClass, Flow};
|
||||||
use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal, mut_base};
|
use flow::{ForceNonfloated, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
|
||||||
|
use flow::{PostorderFlowTraversal, mut_base};
|
||||||
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
|
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
|
||||||
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
|
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
|
||||||
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
|
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
|
||||||
|
@ -569,7 +570,7 @@ impl BlockFlow {
|
||||||
pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
|
pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
|
||||||
let writing_mode = node.style().writing_mode;
|
let writing_mode = node.style().writing_mode;
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: BaseFlow::new(Some((*node).clone()), writing_mode),
|
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
|
||||||
fragment: Fragment::new(constructor, node),
|
fragment: Fragment::new(constructor, node),
|
||||||
static_b_offset: Au::new(0),
|
static_b_offset: Au::new(0),
|
||||||
inline_size_of_preceding_left_floats: Au(0),
|
inline_size_of_preceding_left_floats: Au(0),
|
||||||
|
@ -583,7 +584,7 @@ impl BlockFlow {
|
||||||
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
|
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
|
||||||
let writing_mode = node.style().writing_mode;
|
let writing_mode = node.style().writing_mode;
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: BaseFlow::new(Some((*node).clone()), writing_mode),
|
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
|
||||||
fragment: fragment,
|
fragment: fragment,
|
||||||
static_b_offset: Au::new(0),
|
static_b_offset: Au::new(0),
|
||||||
inline_size_of_preceding_left_floats: Au(0),
|
inline_size_of_preceding_left_floats: Au(0),
|
||||||
|
@ -600,7 +601,7 @@ impl BlockFlow {
|
||||||
-> BlockFlow {
|
-> BlockFlow {
|
||||||
let writing_mode = node.style().writing_mode;
|
let writing_mode = node.style().writing_mode;
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: BaseFlow::new(Some((*node).clone()), writing_mode),
|
base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
|
||||||
fragment: Fragment::new(constructor, node),
|
fragment: Fragment::new(constructor, node),
|
||||||
static_b_offset: Au::new(0),
|
static_b_offset: Au::new(0),
|
||||||
inline_size_of_preceding_left_floats: Au(0),
|
inline_size_of_preceding_left_floats: Au(0),
|
||||||
|
@ -617,7 +618,7 @@ impl BlockFlow {
|
||||||
-> BlockFlow {
|
-> BlockFlow {
|
||||||
let writing_mode = node.style().writing_mode;
|
let writing_mode = node.style().writing_mode;
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: BaseFlow::new(Some((*node).clone()), writing_mode),
|
base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
|
||||||
fragment: fragment,
|
fragment: fragment,
|
||||||
static_b_offset: Au::new(0),
|
static_b_offset: Au::new(0),
|
||||||
inline_size_of_preceding_left_floats: Au(0),
|
inline_size_of_preceding_left_floats: Au(0),
|
||||||
|
@ -866,7 +867,10 @@ impl BlockFlow {
|
||||||
// Assume that the *hypothetical box* for an absolute flow starts immediately
|
// Assume that the *hypothetical box* for an absolute flow starts immediately
|
||||||
// after the block-end border edge of the previous flow.
|
// after the block-end border edge of the previous flow.
|
||||||
kid.as_block().hypothetical_position.b = cur_b;
|
kid.as_block().hypothetical_position.b = cur_b;
|
||||||
|
kid.place_float_if_applicable(layout_context);
|
||||||
|
if !flow::base(kid).flags.is_float() {
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||||
|
}
|
||||||
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
||||||
|
|
||||||
// Skip the collapsing and float processing for absolute flow kids and continue
|
// Skip the collapsing and float processing for absolute flow kids and continue
|
||||||
|
@ -885,10 +889,7 @@ impl BlockFlow {
|
||||||
margin_collapse_info.current_float_ceiling();
|
margin_collapse_info.current_float_ceiling();
|
||||||
}
|
}
|
||||||
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
||||||
|
kid.place_float_if_applicable(layout_context);
|
||||||
let need_to_process_child_floats =
|
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
|
||||||
assert!(need_to_process_child_floats); // As it was a float itself...
|
|
||||||
|
|
||||||
let kid_base = flow::mut_base(kid);
|
let kid_base = flow::mut_base(kid);
|
||||||
floats = kid_base.floats.clone();
|
floats = kid_base.floats.clone();
|
||||||
|
@ -907,8 +908,12 @@ impl BlockFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lay the child out if this was an in-order traversal.
|
// Lay the child out if this was an in-order traversal.
|
||||||
let need_to_process_child_floats =
|
let need_to_process_child_floats = if flow::base(kid).flags.is_float() {
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
kid.place_float_if_applicable(layout_context);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
kid.assign_block_size_for_inorder_child_if_necessary(layout_context)
|
||||||
|
};
|
||||||
|
|
||||||
// Mark flows for layerization if necessary to handle painting order correctly.
|
// Mark flows for layerization if necessary to handle painting order correctly.
|
||||||
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
||||||
|
@ -1066,8 +1071,9 @@ impl BlockFlow {
|
||||||
// has not been calculated yet. (See `calculate_absolute_block_size_and_margins` for that.)
|
// has not been calculated yet. (See `calculate_absolute_block_size_and_margins` for that.)
|
||||||
// Also don't remove the dirty bits if we're a block formatting context since our inline
|
// Also don't remove the dirty bits if we're a block formatting context since our inline
|
||||||
// size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
|
// size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
|
||||||
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
|
if (self.base.flags.is_float() ||
|
||||||
self.formatting_context_type() == NonformattingContext {
|
self.formatting_context_type() == NonformattingContext) &&
|
||||||
|
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1113,8 +1119,13 @@ impl BlockFlow {
|
||||||
self.fragment.margin.block_start);
|
self.fragment.margin.block_start);
|
||||||
|
|
||||||
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||||
self.base.position = self.base.position.translate(&float_offset)
|
let mut origin = LogicalPoint::new(self.base.writing_mode,
|
||||||
.translate(&margin_offset);
|
self.hypothetical_position.i,
|
||||||
|
self.base.position.start.b);
|
||||||
|
origin = origin.add_point(&float_offset).add_point(&margin_offset);
|
||||||
|
self.base.position = LogicalRect::from_point_size(self.base.writing_mode,
|
||||||
|
origin,
|
||||||
|
self.base.position.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1321,7 +1332,8 @@ impl BlockFlow {
|
||||||
// and its inline-size is our content inline-size.
|
// and its inline-size is our content inline-size.
|
||||||
{
|
{
|
||||||
let kid_base = flow::mut_base(kid);
|
let kid_base = flow::mut_base(kid);
|
||||||
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
|
||||||
|
!kid_base.flags.is_float() {
|
||||||
kid_base.position.start.i = inline_start_content_edge
|
kid_base.position.start.i = inline_start_content_edge
|
||||||
}
|
}
|
||||||
kid_base.block_container_inline_size = content_inline_size;
|
kid_base.block_container_inline_size = content_inline_size;
|
||||||
|
@ -1414,9 +1426,9 @@ impl BlockFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
let info = PlacementInfo {
|
let info = PlacementInfo {
|
||||||
size: LogicalSize::new(
|
size: LogicalSize::new(self.fragment.style.writing_mode,
|
||||||
self.fragment.style.writing_mode,
|
self.base.position.size.inline +
|
||||||
self.base.position.size.inline + self.fragment.margin.inline_start_end() +
|
self.fragment.margin.inline_start_end() +
|
||||||
self.fragment.border_padding.inline_start_end(),
|
self.fragment.border_padding.inline_start_end(),
|
||||||
self.fragment.border_box.size.block),
|
self.fragment.border_box.size.block),
|
||||||
ceiling: self.base.position.start.b,
|
ceiling: self.base.position.start.b,
|
||||||
|
@ -1426,10 +1438,12 @@ impl BlockFlow {
|
||||||
|
|
||||||
// Offset our position by whatever displacement is needed to not impact the floats.
|
// Offset our position by whatever displacement is needed to not impact the floats.
|
||||||
let rect = self.base.floats.place_between_floats(&info);
|
let rect = self.base.floats.place_between_floats(&info);
|
||||||
self.base.position.start.i = self.base.position.start.i + rect.start.i;
|
self.base.position.start.i = self.hypothetical_position.i + rect.start.i;
|
||||||
|
|
||||||
// TODO(pcwalton): If the inline-size of this flow is different from the size we estimated
|
// TODO(pcwalton): If the inline-size of this flow is different from the size we estimated
|
||||||
// earlier, lay it out again.
|
// earlier, lay it out again.
|
||||||
|
|
||||||
|
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_inline_block(&self) -> bool {
|
fn is_inline_block(&self) -> bool {
|
||||||
|
@ -1602,19 +1616,17 @@ impl Flow for BlockFlow {
|
||||||
None);
|
None);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assigns block-sizes in-order; or, if this is a float, places the float. The default
|
fn place_float_if_applicable<'a>(&mut self, _: &'a LayoutContext<'a>) {
|
||||||
/// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
|
if self.base.flags.is_float() {
|
||||||
/// if this child affected the floats in the flow somehow or false otherwise; thus, if true,
|
self.place_float();
|
||||||
/// then the parent flow is expected to take the `floats` member of this flow into account.
|
}
|
||||||
///
|
}
|
||||||
/// This is called on child flows by the parent. Hence, we can assume that `assign_block_size`
|
|
||||||
/// has already been called on the child (because of the bottom-up traversal).
|
|
||||||
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
||||||
layout_context: &'a LayoutContext<'a>)
|
layout_context: &'a LayoutContext<'a>)
|
||||||
-> bool {
|
-> bool {
|
||||||
if self.base.flags.is_float() {
|
if self.base.flags.is_float() {
|
||||||
self.place_float();
|
return false
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_formatting_context = self.formatting_context_type() != NonformattingContext;
|
let is_formatting_context = self.formatting_context_type() != NonformattingContext;
|
||||||
|
@ -2010,7 +2022,6 @@ pub trait ISizeAndMarginsComputer {
|
||||||
// We also resize the block itself, to ensure that overflow is not calculated
|
// We also resize the block itself, to ensure that overflow is not calculated
|
||||||
// as the inline-size of our parent. We might be smaller and we might be larger if we
|
// as the inline-size of our parent. We might be smaller and we might be larger if we
|
||||||
// overflow.
|
// overflow.
|
||||||
|
|
||||||
flow::mut_base(block).position.size.inline = inline_size + extra_inline_size_from_margin;
|
flow::mut_base(block).position.size.inline = inline_size + extra_inline_size_from_margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,9 @@ pub trait Flow: fmt::Show + ToString + Sync {
|
||||||
panic!("assign_block_size not yet implemented")
|
panic!("assign_block_size not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If this is a float, places it. The default implementation does nothing.
|
||||||
|
fn place_float_if_applicable<'a>(&mut self, _: &'a LayoutContext<'a>) {}
|
||||||
|
|
||||||
/// Assigns block-sizes in-order; or, if this is a float, places the float. The default
|
/// Assigns block-sizes in-order; or, if this is a float, places the float. The default
|
||||||
/// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
|
/// implementation simply assigns block-sizes if this flow is impacted by floats. Returns true
|
||||||
/// if this child was impacted by floats or false otherwise.
|
/// if this child was impacted by floats or false otherwise.
|
||||||
|
@ -568,7 +571,7 @@ impl FlowFlags {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_float(&self) -> bool {
|
pub fn is_float(&self) -> bool {
|
||||||
self.floats_left() || self.floats_right()
|
self.contains(FLOATS_LEFT) || self.contains(FLOATS_RIGHT)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -835,9 +838,22 @@ impl Drop for BaseFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether a base flow should be forced to be nonfloated. This can affect e.g. `TableFlow`, which
|
||||||
|
/// is never floated because the table wrapper flow is the floated one.
|
||||||
|
#[deriving(Clone, PartialEq)]
|
||||||
|
pub enum ForceNonfloatedFlag {
|
||||||
|
/// The flow should be floated if the node has a `float` property.
|
||||||
|
FloatIfNecessary,
|
||||||
|
/// The flow should be forced to be nonfloated.
|
||||||
|
ForceNonfloated,
|
||||||
|
}
|
||||||
|
|
||||||
impl BaseFlow {
|
impl BaseFlow {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(node: Option<ThreadSafeLayoutNode>, writing_mode: WritingMode) -> BaseFlow {
|
pub fn new(node: Option<ThreadSafeLayoutNode>,
|
||||||
|
writing_mode: WritingMode,
|
||||||
|
force_nonfloated: ForceNonfloatedFlag)
|
||||||
|
-> BaseFlow {
|
||||||
let mut flags = FlowFlags::empty();
|
let mut flags = FlowFlags::empty();
|
||||||
match node {
|
match node {
|
||||||
None => {}
|
None => {}
|
||||||
|
@ -849,11 +865,15 @@ impl BaseFlow {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if force_nonfloated == FloatIfNecessary {
|
||||||
match node_style.get_box().float {
|
match node_style.get_box().float {
|
||||||
float::none => {}
|
float::none => {}
|
||||||
float::left => flags.insert(FLOATS_LEFT),
|
float::left => flags.insert(FLOATS_LEFT),
|
||||||
float::right => flags.insert(FLOATS_RIGHT),
|
float::right => flags.insert(FLOATS_RIGHT),
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match node_style.get_box().clear {
|
match node_style.get_box().clear {
|
||||||
clear::none => {}
|
clear::none => {}
|
||||||
clear::left => flags.insert(CLEARS_LEFT),
|
clear::left => flags.insert(CLEARS_LEFT),
|
||||||
|
|
|
@ -8,7 +8,7 @@ use css::node_style::StyledNode;
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use display_list_builder::{ContentLevel, DisplayListResult, FragmentDisplayListBuilding};
|
use display_list_builder::{ContentLevel, DisplayListResult, FragmentDisplayListBuilding};
|
||||||
use floats::{FloatLeft, Floats, PlacementInfo};
|
use floats::{FloatLeft, Floats, PlacementInfo};
|
||||||
use flow::{BaseFlow, FlowClass, Flow, InlineFlowClass, MutableFlowUtils};
|
use flow::{BaseFlow, FlowClass, Flow, ForceNonfloated, InlineFlowClass, MutableFlowUtils};
|
||||||
use flow::{IS_ABSOLUTELY_POSITIONED};
|
use flow::{IS_ABSOLUTELY_POSITIONED};
|
||||||
use flow;
|
use flow;
|
||||||
use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
|
use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
|
||||||
|
@ -706,7 +706,7 @@ pub struct InlineFlow {
|
||||||
impl InlineFlow {
|
impl InlineFlow {
|
||||||
pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
|
pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
|
||||||
InlineFlow {
|
InlineFlow {
|
||||||
base: BaseFlow::new(None, writing_mode),
|
base: BaseFlow::new(None, writing_mode, ForceNonfloated),
|
||||||
fragments: fragments,
|
fragments: fragments,
|
||||||
lines: Vec::new(),
|
lines: Vec::new(),
|
||||||
minimum_block_size_above_baseline: Au(0),
|
minimum_block_size_above_baseline: Au(0),
|
||||||
|
|
|
@ -11,8 +11,8 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution};
|
||||||
use construct::FlowConstructor;
|
use construct::FlowConstructor;
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use floats::FloatKind;
|
use floats::FloatKind;
|
||||||
use flow::{TableFlowClass, FlowClass, Flow, ImmutableFlowUtils};
|
use flow::{Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, ImmutableFlowUtils};
|
||||||
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
|
use flow::{TableFlowClass};
|
||||||
use fragment::{Fragment, FragmentBoundsIterator};
|
use fragment::{Fragment, FragmentBoundsIterator};
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use model::{IntrinsicISizes, IntrinsicISizesContribution};
|
use model::{IntrinsicISizes, IntrinsicISizesContribution};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
use context::LayoutContext;
|
use context::LayoutContext;
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
use flow::{BaseFlow, TableColGroupFlowClass, FlowClass, Flow};
|
use flow::{BaseFlow, ForceNonfloated, TableColGroupFlowClass, FlowClass, Flow};
|
||||||
use fragment::{Fragment, FragmentBoundsIterator, TableColumnFragment};
|
use fragment::{Fragment, FragmentBoundsIterator, TableColumnFragment};
|
||||||
use layout_debug;
|
use layout_debug;
|
||||||
use wrapper::ThreadSafeLayoutNode;
|
use wrapper::ThreadSafeLayoutNode;
|
||||||
|
@ -44,7 +44,7 @@ impl TableColGroupFlow {
|
||||||
-> TableColGroupFlow {
|
-> TableColGroupFlow {
|
||||||
let writing_mode = node.style().writing_mode;
|
let writing_mode = node.style().writing_mode;
|
||||||
TableColGroupFlow {
|
TableColGroupFlow {
|
||||||
base: BaseFlow::new(Some((*node).clone()), writing_mode),
|
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
|
||||||
fragment: Some(fragment),
|
fragment: Some(fragment),
|
||||||
cols: fragments,
|
cols: fragments,
|
||||||
inline_sizes: vec!(),
|
inline_sizes: vec!(),
|
||||||
|
|
|
@ -79,7 +79,10 @@ impl TableRowFlow {
|
||||||
// cells).
|
// cells).
|
||||||
let mut max_y = Au(0);
|
let mut max_y = Au(0);
|
||||||
for kid in self.block_flow.base.child_iter() {
|
for kid in self.block_flow.base.child_iter() {
|
||||||
|
kid.place_float_if_applicable(layout_context);
|
||||||
|
if !flow::base(kid).flags.is_float() {
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let child_fragment = kid.as_table_cell().fragment();
|
let child_fragment = kid.as_table_cell().fragment();
|
||||||
|
|
|
@ -74,7 +74,10 @@ impl TableRowGroupFlow {
|
||||||
let mut cur_y = block_start_offset;
|
let mut cur_y = block_start_offset;
|
||||||
|
|
||||||
for kid in self.block_flow.base.child_iter() {
|
for kid in self.block_flow.base.child_iter() {
|
||||||
|
kid.place_float_if_applicable(layout_context);
|
||||||
|
if !flow::base(kid).flags.is_float() {
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
kid.assign_block_size_for_inorder_child_if_necessary(layout_context);
|
||||||
|
}
|
||||||
|
|
||||||
let child_node = flow::mut_base(kid);
|
let child_node = flow::mut_base(kid);
|
||||||
child_node.position.start.b = cur_y;
|
child_node.position.start.b = cur_y;
|
||||||
|
|
|
@ -301,6 +301,10 @@ impl Flow for TableWrapperFlow {
|
||||||
self.block_flow.compute_absolute_position()
|
self.block_flow.compute_absolute_position()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn place_float_if_applicable<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
|
||||||
|
self.block_flow.place_float_if_applicable(layout_context)
|
||||||
|
}
|
||||||
|
|
||||||
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
fn assign_block_size_for_inorder_child_if_necessary<'a>(&mut self,
|
||||||
layout_context: &'a LayoutContext<'a>)
|
layout_context: &'a LayoutContext<'a>)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
|
|
@ -184,3 +184,4 @@ fragment=top != ../html/acid2.html acid2_ref.html
|
||||||
== linear_gradients_reverse_a.html linear_gradients_reverse_ref.html
|
== linear_gradients_reverse_a.html linear_gradients_reverse_ref.html
|
||||||
!= linear_gradients_corners_a.html linear_gradients_corners_ref.html
|
!= linear_gradients_corners_a.html linear_gradients_corners_ref.html
|
||||||
== linear_gradients_lengths_a.html linear_gradients_lengths_ref.html
|
== linear_gradients_lengths_a.html linear_gradients_lengths_ref.html
|
||||||
|
== incremental_float_a.html incremental_float_ref.html
|
||||||
|
|
36
tests/ref/incremental_float_a.html
Normal file
36
tests/ref/incremental_float_a.html
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
nav.floaty {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
clear: both;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section>
|
||||||
|
<nav>This floats</nav>
|
||||||
|
<div>This doesn't</div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<nav>This floats</nav>
|
||||||
|
<div style="overflow: hidden;">This is a block formatting context</div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<nav>This floats</nav>
|
||||||
|
<div style="position: absolute; top: 0; left: 0; width: 100px; height: 100px;">
|
||||||
|
This is abspos
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
|
var elements = document.getElementsByTagName('nav');
|
||||||
|
for (var i = 0; i < elements.length; i++)
|
||||||
|
elements[i].setAttribute('class', 'floaty');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
31
tests/ref/incremental_float_ref.html
Normal file
31
tests/ref/incremental_float_ref.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
nav {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
clear: both;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section>
|
||||||
|
<nav>This floats</nav>
|
||||||
|
<div>This doesn't</div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<nav>This floats</nav>
|
||||||
|
<div style="overflow: hidden;">This is a block formatting context</div>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<nav>This floats</nav>
|
||||||
|
<div style="position: absolute; top: 0; left: 0; width: 100px; height: 100px;">
|
||||||
|
This is abspos
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue