aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/flow.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/flow.rs')
-rw-r--r--components/layout/flow.rs72
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
}