diff options
Diffstat (limited to 'components/layout/flow.rs')
-rw-r--r-- | components/layout/flow.rs | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 445a3e5a49c..6b11bee1f8c 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -499,7 +499,7 @@ pub trait MutableOwnedFlowUtils { /// Set absolute descendants for this flow. /// /// Set this flow as the Containing Block for all the absolute descendants. - fn set_absolute_descendants(&mut self, abs_descendants: AbsDescendants); + fn set_absolute_descendants(&mut self, abs_descendants: AbsoluteDescendants); } #[derive(RustcEncodable, PartialEq, Debug)] @@ -694,19 +694,17 @@ impl FlowFlags { } } -/// The Descendants of a flow. -/// -/// Also, details about their position wrt this flow. +/// Absolutely-positioned descendants of this flow. #[derive(Clone)] -pub struct Descendants { +pub struct AbsoluteDescendants { /// Links to every descendant. This must be private because it is unsafe to leak `FlowRef`s to /// layout. - descendant_links: Vec<FlowRef>, + descendant_links: Vec<AbsoluteDescendantInfo>, } -impl Descendants { - pub fn new() -> Descendants { - Descendants { +impl AbsoluteDescendants { + pub fn new() -> AbsoluteDescendants { + AbsoluteDescendants { descendant_links: Vec::new(), } } @@ -720,40 +718,63 @@ impl Descendants { } pub fn push(&mut self, given_descendant: FlowRef) { - self.descendant_links.push(given_descendant); + self.descendant_links.push(AbsoluteDescendantInfo { + flow: given_descendant, + }); } /// Push the given descendants on to the existing descendants. /// /// Ignore any static y offsets, because they are None before layout. - pub fn push_descendants(&mut self, given_descendants: Descendants) { + pub fn push_descendants(&mut self, given_descendants: AbsoluteDescendants) { for elem in given_descendants.descendant_links.into_iter() { self.descendant_links.push(elem); } } /// Return an iterator over the descendant flows. - pub fn iter<'a>(&'a mut self) -> DescendantIter<'a> { - DescendantIter { + pub fn iter<'a>(&'a mut self) -> AbsoluteDescendantIter<'a> { + AbsoluteDescendantIter { iter: self.descendant_links.iter_mut(), } } } -pub type AbsDescendants = Descendants; +/// TODO(pcwalton): This structure is going to need a flag to record whether the absolute +/// descendants have reached their containing block yet. The reason is so that we can handle cases +/// like the following: +/// +/// <div> +/// <span id=a style="position: absolute; ...">foo</span> +/// <span style="position: relative"> +/// <span id=b style="position: absolute; ...">bar</span> +/// </span> +/// </div> +/// +/// When we go to create the `InlineFlow` for the outer `div`, our absolute descendants will +/// be `a` and `b`. At this point, we need a way to distinguish between the two, because the +/// containing block for `a` will be different from the containing block for `b`. Specifically, +/// the latter's containing block is the inline flow itself, while the former's containing +/// block is going to be some parent of the outer `div`. Hence we need this flag as a way to +/// distinguish the two; it will be false for `a` and true for `b`. +#[derive(Clone)] +pub struct AbsoluteDescendantInfo { + /// The absolute descendant flow in question. + flow: FlowRef, +} -pub struct DescendantIter<'a> { - iter: IterMut<'a, FlowRef>, +pub struct AbsoluteDescendantIter<'a> { + iter: IterMut<'a, AbsoluteDescendantInfo>, } -impl<'a> Iterator for DescendantIter<'a> { +impl<'a> Iterator for AbsoluteDescendantIter<'a> { type Item = &'a mut (Flow + 'a); fn next(&mut self) -> Option<&'a mut (Flow + 'a)> { - self.iter.next().map(|flow| &mut **flow) + self.iter.next().map(|info| &mut *info.flow) } } -pub type DescendantOffsetIter<'a> = Zip<DescendantIter<'a>, IterMut<'a, Au>>; +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). @@ -837,7 +858,7 @@ pub struct BaseFlow { /// Details about descendants with position 'absolute' or 'fixed' for which we are the /// containing block. This is in tree order. This includes any direct children. - pub abs_descendants: AbsDescendants, + pub abs_descendants: AbsoluteDescendants, /// The inline-size of the block container of this flow. Used for computing percentage and /// automatic values for `width`. @@ -1034,7 +1055,7 @@ impl BaseFlow { floats: Floats::new(writing_mode), collapsible_margins: CollapsibleMargins::new(), stacking_relative_position: Point2D::zero(), - abs_descendants: Descendants::new(), + abs_descendants: AbsoluteDescendants::new(), block_container_inline_size: Au(0), block_container_writing_mode: writing_mode, block_container_explicit_block_size: None, @@ -1367,7 +1388,7 @@ impl MutableOwnedFlowUtils for FlowRef { /// This is called during flow construction, so nothing else can be accessing the descendant /// flows. This is enforced by the fact that we have a mutable `FlowRef`, which only flow /// construction is allowed to possess. - fn set_absolute_descendants(&mut self, abs_descendants: AbsDescendants) { + fn set_absolute_descendants(&mut self, abs_descendants: AbsoluteDescendants) { let this = self.clone(); let base = mut_base(&mut **self); base.abs_descendants = abs_descendants; @@ -1414,7 +1435,10 @@ impl ContainingBlockLink { panic!("Link to containing block not established; perhaps you forgot to call \ `set_absolute_descendants`?") } - Some(ref link) => link.upgrade().unwrap().generated_containing_block_size(for_flow), + Some(ref link) => { + let flow = link.upgrade().unwrap(); + flow.generated_containing_block_size(for_flow) + } } } @@ -1429,6 +1453,8 @@ impl ContainingBlockLink { let flow = link.upgrade().unwrap(); if flow.is_block_like() { flow.as_immutable_block().explicit_block_containing_size(layout_context) + } else if flow.is_inline_flow() { + Some(flow.as_immutable_inline().minimum_block_size_above_baseline) } else { None } |