aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/block.rs54
-rw-r--r--components/layout/data.rs2
-rw-r--r--components/layout/display_list_builder.rs24
-rw-r--r--components/layout/flex.rs4
-rw-r--r--components/layout/flow.rs90
-rw-r--r--components/layout/fragment.rs15
-rw-r--r--components/layout/incremental.rs4
-rw-r--r--components/layout/inline.rs28
-rw-r--r--components/layout/list_item.rs4
-rw-r--r--components/layout/table.rs16
-rw-r--r--components/layout/table_row.rs12
-rw-r--r--components/layout/table_wrapper.rs75
-rw-r--r--components/layout/traversal.rs4
13 files changed, 246 insertions, 86 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index d697cad97a9..3926384379a 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -36,10 +36,10 @@ use flow::{CLEARS_LEFT, CLEARS_RIGHT};
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC};
use flow::{IS_ABSOLUTELY_POSITIONED};
-use flow::{ImmutableFlowUtils, MutableFlowUtils, OpaqueFlow, PreorderFlowTraversal};
+use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow};
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
-use flow::{PostorderFlowTraversal, mut_base};
-use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
+use flow::{PostorderFlowTraversal, PreorderFlowTraversal, mut_base};
+use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, ForceNonfloatedFlag, FlowClass, Flow};
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, HAS_LAYER};
use fragment::{SpecificFragmentInfo};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
@@ -485,7 +485,7 @@ impl<'a> PostorderFlowTraversal for AbsoluteStoreOverflowTraversal<'a> {
}
}
- flow.store_overflow(self.layout_context);
+ flow.early_store_overflow(self.layout_context);
}
}
@@ -561,7 +561,7 @@ pub struct BlockFlow {
bitflags! {
flags BlockFlowFlags: u8 {
- #[doc="If this is set, then this block flow is the root flow."]
+ #[doc = "If this is set, then this block flow is the root flow."]
const IS_ROOT = 0x01,
}
}
@@ -959,6 +959,19 @@ impl BlockFlow {
//
// FIXME(pcwalton): This looks not idempotent. Is it?
self.fragment.border_box.size.block = block_size;
+ }
+
+ // Write in the size of the relative containing block for children. (This information
+ // is also needed to handle RTL.)
+ for kid in self.base.child_iter() {
+ flow::mut_base(kid).early_absolute_position_info = EarlyAbsolutePositionInfo {
+ relative_containing_block_size: self.fragment.content_box().size,
+ relative_containing_block_mode: self.fragment.style().writing_mode,
+ };
+ kid.late_store_overflow(layout_context)
+ }
+
+ if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
return
}
@@ -1730,7 +1743,7 @@ impl Flow for BlockFlow {
self.base.thread_id = parent_thread_id;
if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
self.assign_block_size(layout_context);
- self.store_overflow(layout_context);
+ (self as &mut Flow).early_store_overflow(layout_context);
// Don't remove the restyle damage; `assign_block_size` decides whether that is
// appropriate (which in the case of e.g. absolutely-positioned flows, it is not).
}
@@ -1775,7 +1788,7 @@ impl Flow for BlockFlow {
fn compute_absolute_position(&mut self, layout_context: &LayoutContext) {
if (self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
- self.base.absolute_position_info.layers_needed_for_positioned_flows) ||
+ self.base.late_absolute_position_info.layers_needed_for_positioned_flows) ||
self.base.flags.contains(NEEDS_LAYER) {
self.fragment.flags.insert(HAS_LAYER)
}
@@ -1816,7 +1829,7 @@ impl Flow for BlockFlow {
// Absolute position of the containing block + position of absolute
// flow w.r.t. the containing block.
self.base
- .absolute_position_info
+ .late_absolute_position_info
.stacking_relative_position_of_absolute_containing_block + position_start
};
@@ -1842,13 +1855,13 @@ impl Flow for BlockFlow {
// other hand, is only established if we are positioned.
let relative_offset =
self.fragment.relative_position(&self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size);
if self.contains_positioned_fragments() {
let border_box_origin = (self.fragment.border_box -
self.fragment.style.logical_border_width()).start;
self.base
- .absolute_position_info
+ .late_absolute_position_info
.stacking_relative_position_of_absolute_containing_block =
self.base.stacking_relative_position +
(border_box_origin + relative_offset).to_physical(self.base.writing_mode,
@@ -1875,14 +1888,12 @@ impl Flow for BlockFlow {
}
} else {
self.base
- .absolute_position_info
+ .late_absolute_position_info
.stacking_relative_position_of_absolute_containing_block
};
- let absolute_position_info_for_children = AbsolutePositionInfo {
+ let late_absolute_position_info_for_children = LateAbsolutePositionInfo {
stacking_relative_position_of_absolute_containing_block:
stacking_relative_position_of_absolute_containing_block_for_children,
- relative_containing_block_size: self.fragment.content_box().size,
- relative_containing_block_mode: self.base.writing_mode,
layers_needed_for_positioned_flows: self.base
.flags
.contains(LAYERS_NEEDED_FOR_DESCENDANTS),
@@ -1934,10 +1945,10 @@ impl Flow for BlockFlow {
self.fragment
.stacking_relative_border_box(&self.base.stacking_relative_position,
&self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size,
self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_mode,
CoordinateSystem::Own);
let clip = self.fragment.clipping_region_for_children(
@@ -1985,7 +1996,8 @@ impl Flow for BlockFlow {
}
}
- flow::mut_base(kid).absolute_position_info = absolute_position_info_for_children;
+ flow::mut_base(kid).late_absolute_position_info =
+ late_absolute_position_info_for_children;
flow::mut_base(kid).clip = clip.clone();
flow::mut_base(kid).stacking_relative_position_of_display_port =
stacking_relative_position_of_display_port_for_children;
@@ -2056,7 +2068,9 @@ impl Flow for BlockFlow {
}
fn compute_overflow(&self) -> Rect<Au> {
- self.fragment.compute_overflow()
+ self.fragment.compute_overflow(&self.base
+ .early_absolute_position_info
+ .relative_containing_block_size)
}
fn iterate_through_fragment_border_boxes(&self,
@@ -2072,10 +2086,10 @@ impl Flow for BlockFlow {
&self.fragment
.stacking_relative_border_box(&self.base.stacking_relative_position,
&self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size,
self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_mode,
CoordinateSystem::Own)
.translate(stacking_context_position));
diff --git a/components/layout/data.rs b/components/layout/data.rs
index 4b551e2fd9e..097852096fa 100644
--- a/components/layout/data.rs
+++ b/components/layout/data.rs
@@ -54,7 +54,7 @@ impl PrivateLayoutData {
bitflags! {
flags LayoutDataFlags: u8 {
- #[doc="Whether a flow has been newly constructed."]
+ #[doc = "Whether a flow has been newly constructed."]
const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01
}
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 0485d549c4a..19c466ee528 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -1152,9 +1152,9 @@ impl FragmentDisplayListBuilding for Fragment {
StackingContextCreationMode::Normal |
StackingContextCreationMode::OuterScrollWrapper => {
self.stacking_relative_border_box(&base_flow.stacking_relative_position,
- &base_flow.absolute_position_info
+ &base_flow.early_absolute_position_info
.relative_containing_block_size,
- base_flow.absolute_position_info
+ base_flow.early_absolute_position_info
.relative_containing_block_mode,
CoordinateSystem::Parent)
}
@@ -1533,8 +1533,12 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
.build_display_list(display_list,
layout_context,
&self.base.stacking_relative_position,
- &self.base.absolute_position_info.relative_containing_block_size,
- self.base.absolute_position_info.relative_containing_block_mode,
+ &self.base
+ .early_absolute_position_info
+ .relative_containing_block_size,
+ self.base
+ .early_absolute_position_info
+ .relative_containing_block_mode,
border_painting_mode,
background_border_level,
&clip,
@@ -1616,8 +1620,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&mut outer_display_list_for_overflow_scroll,
layout_context,
&self.base.stacking_relative_position,
- &self.base.absolute_position_info.relative_containing_block_size,
- self.base.absolute_position_info.relative_containing_block_mode,
+ &self.base.early_absolute_position_info.relative_containing_block_size,
+ self.base.early_absolute_position_info.relative_containing_block_mode,
border_painting_mode,
BackgroundAndBorderLevel::RootOfStackingContext,
&clip,
@@ -1775,10 +1779,10 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
layout_context,
&self.base.stacking_relative_position,
&self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size,
self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_mode,
BorderPaintingMode::Separate,
BackgroundAndBorderLevel::Content,
@@ -1857,11 +1861,11 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
&self.block_flow.base.stacking_relative_position,
&self.block_flow
.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size,
self.block_flow
.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_mode,
BorderPaintingMode::Separate,
BackgroundAndBorderLevel::Content,
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index 3c34aeaf728..88fe929a9d3 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -312,6 +312,10 @@ impl Flow for FlexFlow {
&mut self.block_flow
}
+ fn mark_as_root(&mut self) {
+ self.block_flow.mark_as_root();
+ }
+
fn bubble_inline_sizes(&mut self) {
let _scope = layout_debug_scope!("flex::bubble_inline_sizes {:x}",
self.block_flow.base.debug_id());
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 6d319bdd991..4e2da89f513 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -222,7 +222,11 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
if impacted {
mut_base(self).thread_id = parent_thread_id;
self.assign_block_size(layout_context);
- self.store_overflow(layout_context);
+ // FIXME(pcwalton): Should use `early_store_overflow()` here but that fails due to a
+ // compiler bug (`Self` does not have a constant size).
+ if !self.contains_relatively_positioned_fragments() {
+ self.store_overflow(layout_context)
+ }
mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
}
impacted
@@ -246,7 +250,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
match self.class() {
FlowClass::Block |
FlowClass::TableCaption |
- FlowClass::TableCell if !base(self).children.is_empty() => {
+ FlowClass::TableCell => {
// FIXME(#2795): Get the real container size.
let container_size = Size2D::zero();
for kid in mut_base(self).children.iter_mut() {
@@ -310,13 +314,6 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
// different behaviour for different types of Flow, so they can't go into
// the Immutable / Mutable Flow Utils traits without additional casts.
- /// Return true if store overflow is delayed for this flow.
- ///
- /// Currently happens only for absolutely positioned flows.
- fn is_store_overflow_delayed(&mut self) -> bool {
- false
- }
-
fn is_root(&self) -> bool {
false
}
@@ -459,6 +456,11 @@ pub trait ImmutableFlowUtils {
/// Returns true if this flow is an inline flow.
fn is_inline_flow(self) -> bool;
+ /// Returns true if this flow can have its overflow area calculated early (during its
+ /// block-size assignment) or false if it must have its overflow area calculated late (during
+ /// its parent's block-size assignment).
+ fn can_calculate_overflow_area_early(self) -> bool;
+
/// Dumps the flow tree for debugging.
fn dump(self);
@@ -495,6 +497,12 @@ pub trait MutableFlowUtils {
/// Calls `repair_style` and `bubble_inline_sizes`. You should use this method instead of
/// calling them individually, since there is no reason not to perform both operations.
fn repair_style_and_bubble_inline_sizes(self, style: &Arc<ComputedValues>);
+
+ /// Calls `store_overflow()` if the overflow can be calculated early.
+ fn early_store_overflow(self, layout_context: &LayoutContext);
+
+ /// Calls `store_overflow()` if the overflow cannot be calculated early.
+ fn late_store_overflow(self, layout_context: &LayoutContext);
}
pub trait MutableOwnedFlowUtils {
@@ -780,15 +788,30 @@ impl<'a> Iterator for AbsoluteDescendantIter<'a> {
pub type AbsoluteDescendantOffsetIter<'a> = Zip<AbsoluteDescendantIter<'a>, IterMut<'a, Au>>;
/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
-/// confused with absolutely-positioned flows).
-#[derive(RustcEncodable, Copy, Clone)]
-pub struct AbsolutePositionInfo {
+/// confused with absolutely-positioned flows) that is computed during block-size assignment.
+pub struct EarlyAbsolutePositionInfo {
/// The size of the containing block for relatively-positioned descendants.
pub relative_containing_block_size: LogicalSize<Au>,
/// The writing mode for `relative_containing_block_size`.
pub relative_containing_block_mode: WritingMode,
+}
+
+impl EarlyAbsolutePositionInfo {
+ pub fn new(writing_mode: WritingMode) -> EarlyAbsolutePositionInfo {
+ // FIXME(pcwalton): The initial relative containing block-size should be equal to the size
+ // of the root layer.
+ EarlyAbsolutePositionInfo {
+ relative_containing_block_size: LogicalSize::zero(writing_mode),
+ relative_containing_block_mode: writing_mode,
+ }
+ }
+}
+/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
+/// confused with absolutely-positioned flows) that is computed during final position assignment.
+#[derive(RustcEncodable, Copy, Clone)]
+pub struct LateAbsolutePositionInfo {
/// The position of the absolute containing block relative to the nearest ancestor stacking
/// context. If the absolute containing block establishes the stacking context for this flow,
/// and this flow is not itself absolutely-positioned, then this is (0, 0).
@@ -800,13 +823,9 @@ pub struct AbsolutePositionInfo {
pub layers_needed_for_positioned_flows: bool,
}
-impl AbsolutePositionInfo {
- pub fn new(writing_mode: WritingMode) -> AbsolutePositionInfo {
- // FIXME(pcwalton): The initial relative containing block-size should be equal to the size
- // of the root layer.
- AbsolutePositionInfo {
- relative_containing_block_size: LogicalSize::zero(writing_mode),
- relative_containing_block_mode: writing_mode,
+impl LateAbsolutePositionInfo {
+ pub fn new() -> LateAbsolutePositionInfo {
+ LateAbsolutePositionInfo {
stacking_relative_position_of_absolute_containing_block: Point2D::zero(),
layers_needed_for_positioned_flows: false,
}
@@ -875,8 +894,13 @@ pub struct BaseFlow {
pub absolute_cb: ContainingBlockLink,
/// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
- /// confused with absolutely-positioned flows).
- pub absolute_position_info: AbsolutePositionInfo,
+ /// confused with absolutely-positioned flows) that is computed during block-size assignment.
+ pub early_absolute_position_info: EarlyAbsolutePositionInfo,
+
+ /// Information needed to compute absolute (i.e. viewport-relative) flow positions (not to be
+ /// confused with absolutely-positioned flows) that is computed during final position
+ /// assignment.
+ pub late_absolute_position_info: LateAbsolutePositionInfo,
/// The clipping region for this flow and its descendants, in layer coordinates.
pub clip: ClippingRegion,
@@ -1038,7 +1062,8 @@ impl BaseFlow {
block_container_explicit_block_size: None,
absolute_cb: ContainingBlockLink::new(),
display_list_building_result: DisplayListBuildingResult::None,
- absolute_position_info: AbsolutePositionInfo::new(writing_mode),
+ early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
+ late_absolute_position_info: LateAbsolutePositionInfo::new(),
clip: ClippingRegion::max(),
stacking_relative_position_of_display_port: Rect::zero(),
flags: flags,
@@ -1276,6 +1301,13 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
}
}
+ /// Returns true if this flow can have its overflow area calculated early (during its
+ /// block-size assignment) or false if it must have its overflow area calculated late (during
+ /// its parent's block-size assignment).
+ fn can_calculate_overflow_area_early(self) -> bool {
+ !self.contains_relatively_positioned_fragments()
+ }
+
/// Dumps the flow tree for debugging.
fn dump(self) {
self.dump_with_level(0)
@@ -1354,6 +1386,20 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
traversal.process(*self)
}
+
+ /// Calls `store_overflow()` if the overflow can be calculated early.
+ fn early_store_overflow(self, layout_context: &LayoutContext) {
+ if self.can_calculate_overflow_area_early() {
+ self.store_overflow(layout_context)
+ }
+ }
+
+ /// Calls `store_overflow()` if the overflow cannot be calculated early.
+ fn late_store_overflow(self, layout_context: &LayoutContext) {
+ if !self.can_calculate_overflow_area_early() {
+ self.store_overflow(layout_context)
+ }
+ }
}
impl MutableOwnedFlowUtils for FlowRef {
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 02af5569d84..3b9596d27b9 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -2049,7 +2049,7 @@ impl Fragment {
}
/// Computes the overflow rect of this fragment relative to the start of the flow.
- pub fn compute_overflow(&self) -> Rect<Au> {
+ pub fn compute_overflow(&self, relative_containing_block_size: &LogicalSize<Au>) -> Rect<Au> {
// FIXME(pcwalton, #2795): Get the real container size.
let container_size = Size2D::zero();
let mut border_box = self.border_box.to_physical(self.style.writing_mode, container_size);
@@ -2058,10 +2058,9 @@ impl Fragment {
//
// FIXME(pcwalton): I'm not a fan of the way this makes us crawl though so many styles all
// the time. Can't we handle relative positioning by just adjusting `border_box`?
- let relative_position =
- self.relative_position(&LogicalSize::zero(self.style.writing_mode));
- border_box = border_box.translate_by_size(&relative_position.to_physical(
- self.style.writing_mode));
+ let relative_position = self.relative_position(relative_containing_block_size);
+ border_box =
+ border_box.translate_by_size(&relative_position.to_physical(self.style.writing_mode));
let mut overflow = border_box;
// Box shadows cause us to draw outside our border box.
@@ -2300,10 +2299,10 @@ bitflags! {
// Various flags we can use when splitting fragments. See
// `calculate_split_position_using_breaking_strategy()`.
flags SplitOptions: u8 {
- #[doc="True if this is the first fragment on the line."]
+ #[doc = "True if this is the first fragment on the line."]
const STARTS_LINE = 0x01,
- #[doc="True if we should attempt to split at character boundaries if this split fails. \
- This is used to implement `overflow-wrap: break-word`."]
+ #[doc = "True if we should attempt to split at character boundaries if this split fails. \
+ This is used to implement `overflow-wrap: break-word`."]
const RETRY_AT_CHARACTER_BOUNDARIES = 0x02,
}
}
diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs
index 623fa4685fe..14205b32cb5 100644
--- a/components/layout/incremental.rs
+++ b/components/layout/incremental.rs
@@ -42,8 +42,8 @@ bitflags! {
bitflags! {
flags SpecialRestyleDamage: u8 {
- #[doc="If this flag is set, we need to reflow the entire document. This is more or less a \
- temporary hack to deal with cases that we don't handle incrementally yet."]
+ #[doc = "If this flag is set, we need to reflow the entire document. This is more or less a \
+ temporary hack to deal with cases that we don't handle incrementally yet."]
const REFLOW_ENTIRE_DOCUMENT = 0x01,
}
}
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 4b5a6b985c7..17d6af7ccbc 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -183,9 +183,9 @@ int_range_index! {
bitflags! {
flags InlineReflowFlags: u8 {
- #[doc="The `white-space: nowrap` property from CSS 2.1 § 16.6 is in effect."]
+ #[doc = "The `white-space: nowrap` property from CSS 2.1 § 16.6 is in effect."]
const NO_WRAP_INLINE_REFLOW_FLAG = 0x01,
- #[doc="The `white-space: pre` property from CSS 2.1 § 16.6 is in effect."]
+ #[doc = "The `white-space: pre` property from CSS 2.1 § 16.6 is in effect."]
const WRAP_ON_NEWLINE_INLINE_REFLOW_FLAG = 0x02
}
}
@@ -1645,10 +1645,10 @@ impl Flow for InlineFlow {
let stacking_relative_border_box =
fragment.stacking_relative_border_box(&self.base.stacking_relative_position,
&self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size,
self.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_mode,
CoordinateSystem::Parent);
let clip = fragment.clipping_region_for_children(&self.base.clip,
@@ -1661,13 +1661,14 @@ impl Flow for InlineFlow {
flow::mut_base(flow).clip = clip;
let block_flow = flow.as_mut_block();
- block_flow.base.absolute_position_info = self.base.absolute_position_info;
+ block_flow.base.late_absolute_position_info =
+ self.base.late_absolute_position_info;
let stacking_relative_position = self.base.stacking_relative_position;
if is_positioned {
let padding_box_origin = containing_block_positions.next().unwrap();
block_flow.base
- .absolute_position_info
+ .late_absolute_position_info
.stacking_relative_position_of_absolute_containing_block =
stacking_relative_position + *padding_box_origin;
}
@@ -1681,7 +1682,8 @@ impl Flow for InlineFlow {
let flow = flow_ref::deref_mut(&mut info.flow_ref);
flow::mut_base(flow).clip = clip;
let block_flow = flow.as_mut_block();
- block_flow.base.absolute_position_info = self.base.absolute_position_info;
+ block_flow.base.late_absolute_position_info =
+ self.base.late_absolute_position_info;
block_flow.base.stacking_relative_position =
stacking_relative_border_box.origin;
@@ -1693,12 +1695,13 @@ impl Flow for InlineFlow {
flow::mut_base(flow).clip = clip;
let block_flow = flow.as_mut_block();
- block_flow.base.absolute_position_info = self.base.absolute_position_info;
+ block_flow.base.late_absolute_position_info =
+ self.base.late_absolute_position_info;
let stacking_relative_position = self.base.stacking_relative_position;
let padding_box_origin = containing_block_positions.next().unwrap();
block_flow.base
- .absolute_position_info
+ .late_absolute_position_info
.stacking_relative_position_of_absolute_containing_block =
stacking_relative_position + *padding_box_origin;
@@ -1725,7 +1728,8 @@ impl Flow for InlineFlow {
fn compute_overflow(&self) -> Rect<Au> {
let mut overflow = ZERO_RECT;
for fragment in &self.fragments.fragments {
- overflow = overflow.union(&fragment.compute_overflow())
+ overflow = overflow.union(&fragment.compute_overflow(
+ &self.base.early_absolute_position_info.relative_containing_block_size))
}
overflow
}
@@ -1742,9 +1746,9 @@ impl Flow for InlineFlow {
let stacking_relative_position = &self.base.stacking_relative_position;
let relative_containing_block_size =
- &self.base.absolute_position_info.relative_containing_block_size;
+ &self.base.early_absolute_position_info.relative_containing_block_size;
let relative_containing_block_mode =
- self.base.absolute_position_info.relative_containing_block_mode;
+ self.base.early_absolute_position_info.relative_containing_block_mode;
iterator.process(fragment,
level,
&fragment.stacking_relative_border_box(stacking_relative_position,
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index b0c3702f2c2..7ba0786f906 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -184,11 +184,11 @@ impl Flow for ListItemFlow {
.stacking_relative_position,
&self.block_flow
.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_size,
self.block_flow
.base
- .absolute_position_info
+ .early_absolute_position_info
.relative_containing_block_mode,
CoordinateSystem::Own)
.translate(stacking_context_position));
diff --git a/components/layout/table.rs b/components/layout/table.rs
index f5ef95f1989..54e3f090b59 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -10,8 +10,8 @@ use block::{ISizeConstraintInput, ISizeConstraintSolution};
use block::{self, BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
-use flow::{ImmutableFlowUtils, OpaqueFlow};
-use flow::{self, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
+use flow::{IMPACTED_BY_RIGHT_FLOATS, ImmutableFlowUtils, MutableFlowUtils, OpaqueFlow};
+use flow::{self, EarlyAbsolutePositionInfo, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS};
use fragment::{Fragment, FragmentBorderBoxIterator};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
@@ -761,7 +761,7 @@ pub trait TableLikeFlow {
impl TableLikeFlow for BlockFlow {
fn assign_block_size_for_table_like_flow<'a>(&mut self,
- _: &'a LayoutContext<'a>,
+ layout_context: &'a LayoutContext<'a>,
block_direction_spacing: Au) {
debug_assert!(self.fragment.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate || block_direction_spacing == Au(0));
@@ -838,6 +838,16 @@ impl TableLikeFlow for BlockFlow {
self.fragment.border_box.size.block = current_block_offset;
self.fragment.border_box.start.b = Au(0);
self.base.position.size.block = current_block_offset;
+
+ // Write in the size of the relative containing block for children. (This information
+ // is also needed to handle RTL.)
+ for kid in self.base.child_iter() {
+ flow::mut_base(kid).early_absolute_position_info = EarlyAbsolutePositionInfo {
+ relative_containing_block_size: self.fragment.content_box().size,
+ relative_containing_block_mode: self.fragment.style().writing_mode,
+ };
+ kid.late_store_overflow(layout_context)
+ }
}
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index e2b155bca78..4043363a23a 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -9,7 +9,7 @@
use block::{BlockFlow, ISizeAndMarginsComputer};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
-use flow::{self, FlowClass, Flow, ImmutableFlowUtils, OpaqueFlow};
+use flow::{self, EarlyAbsolutePositionInfo, FlowClass, Flow, ImmutableFlowUtils, OpaqueFlow};
use flow_list::MutFlowListIterator;
use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
@@ -162,7 +162,15 @@ impl TableRowFlow {
}
// Assign the child's block size.
- child_table_cell.block_flow.base.position.size.block = block_size
+ child_table_cell.block_flow.base.position.size.block = block_size;
+
+ // Write in the size of the relative containing block for children. (This information
+ // is also needed to handle RTL.)
+ child_table_cell.block_flow.base.early_absolute_position_info =
+ EarlyAbsolutePositionInfo {
+ relative_containing_block_size: self.block_flow.fragment.content_box().size,
+ relative_containing_block_mode: self.block_flow.fragment.style().writing_mode,
+ };
}
}
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index c3312bceba9..ebf96020634 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -13,12 +13,12 @@
#![deny(unsafe_code)]
-use block::{BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
+use block::{BlockFlow, FloatNonReplaced, AbsoluteNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
use block::{ISizeConstraintSolution, MarginsMayCollapseFlag};
use context::LayoutContext;
use floats::FloatKind;
use flow::{FlowClass, Flow, ImmutableFlowUtils};
-use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, OpaqueFlow};
+use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator};
use model::MaybeAuto;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
@@ -242,6 +242,26 @@ impl TableWrapperFlow {
return
}
+ if !self.block_flow.base.flags.contains(INLINE_POSITION_IS_STATIC) {
+ let inline_size_computer = AbsoluteTable {
+ minimum_width_of_all_columns: minimum_width_of_all_columns,
+ preferred_width_of_all_columns: preferred_width_of_all_columns,
+ border_collapse: border_collapse,
+ };
+ let input =
+ inline_size_computer.compute_inline_size_constraint_inputs(&mut self.block_flow,
+ parent_flow_inline_size,
+ layout_context);
+
+ let solution = inline_size_computer.solve_inline_size_constraints(&mut self.block_flow,
+ &input);
+ inline_size_computer.set_inline_size_constraint_solutions(&mut self.block_flow,
+ solution);
+ inline_size_computer.set_inline_position_of_flow_if_necessary(&mut self.block_flow,
+ solution);
+ return
+ }
+
let inline_size_computer = Table {
minimum_width_of_all_columns: minimum_width_of_all_columns,
preferred_width_of_all_columns: preferred_width_of_all_columns,
@@ -791,3 +811,54 @@ impl ISizeAndMarginsComputer for FloatedTable {
FloatNonReplaced.solve_inline_size_constraints(block, input)
}
}
+
+struct AbsoluteTable {
+ minimum_width_of_all_columns: Au,
+ preferred_width_of_all_columns: Au,
+ border_collapse: border_collapse::T,
+}
+
+impl ISizeAndMarginsComputer for AbsoluteTable {
+ fn compute_border_and_padding(&self, block: &mut BlockFlow, containing_block_inline_size: Au) {
+ block.fragment.compute_border_and_padding(containing_block_inline_size,
+ self.border_collapse)
+ }
+
+ fn initial_computed_inline_size(&self,
+ block: &mut BlockFlow,
+ parent_flow_inline_size: Au,
+ layout_context: &LayoutContext)
+ -> MaybeAuto {
+ let containing_block_inline_size =
+ self.containing_block_inline_size(block,
+ parent_flow_inline_size,
+ layout_context);
+ initial_computed_inline_size(block,
+ containing_block_inline_size,
+ self.minimum_width_of_all_columns,
+ self.preferred_width_of_all_columns)
+ }
+
+ fn containing_block_inline_size(&self,
+ block: &mut BlockFlow,
+ parent_flow_inline_size: Au,
+ layout_context: &LayoutContext)
+ -> Au {
+ AbsoluteNonReplaced.containing_block_inline_size(block, parent_flow_inline_size, layout_context)
+ }
+
+ fn solve_inline_size_constraints(&self,
+ block: &mut BlockFlow,
+ input: &ISizeConstraintInput)
+ -> ISizeConstraintSolution {
+ AbsoluteNonReplaced.solve_inline_size_constraints(block, input)
+ }
+
+ fn set_inline_position_of_flow_if_necessary(&self,
+ block: &mut BlockFlow,
+ solution: ISizeConstraintSolution) {
+ AbsoluteNonReplaced.set_inline_position_of_flow_if_necessary(block, solution);
+ }
+
+}
+
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index 7c4687a1b00..ed8ae6ab76a 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -7,7 +7,7 @@
use construct::FlowConstructor;
use context::LayoutContext;
use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult};
-use flow::{PreorderFlowTraversal, PostorderFlowTraversal};
+use flow::{MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
use flow::{self, Flow};
use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
use script::layout_interface::ReflowGoal;
@@ -368,7 +368,7 @@ impl<'a> PostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {
}
flow.assign_block_size(self.layout_context);
- flow.store_overflow(self.layout_context);
+ flow.early_store_overflow(self.layout_context);
}
#[inline]