aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/construct.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r--components/layout/construct.rs67
1 files changed, 57 insertions, 10 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 53ddc2bed04..36c5742e053 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -31,7 +31,7 @@ use incremental::{BUBBLE_ISIZES, RECONSTRUCT_FLOW, RestyleDamage};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, InlineFragmentNodeFlags};
use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT};
use list_item::{ListItemFlow, ListStyleTypeContent};
-use multicol::MulticolFlow;
+use multicol::{MulticolFlow, MulticolColumnFlow};
use parallel;
use script::dom::bindings::inheritance::{CharacterDataTypeId, ElementTypeId};
use script::dom::bindings::inheritance::{HTMLElementTypeId, NodeTypeId};
@@ -754,12 +754,12 @@ impl<'a, 'ln, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'ln>>
/// to happen.
fn build_flow_for_block(&mut self, node: &ConcreteThreadSafeLayoutNode, float_kind: Option<FloatKind>)
-> ConstructionResult {
- let fragment = self.build_fragment_for_block(node);
- let flow: FlowRef = if node.style().is_multicol() {
- Arc::new(MulticolFlow::from_fragment(fragment, float_kind))
- } else {
- Arc::new(BlockFlow::from_fragment(fragment, float_kind))
- };
+ if node.style().is_multicol() {
+ return self.build_flow_for_multicol(node, float_kind)
+ }
+
+ let flow: FlowRef = Arc::new(
+ BlockFlow::from_fragment(self.build_fragment_for_block(node), float_kind));
self.build_flow_for_block_like(flow, node)
}
@@ -1078,6 +1078,53 @@ impl<'a, 'ln, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'ln>>
flow.add_new_child(anonymous_flow);
}
+ /// Builds a flow for a node with `column-count` or `column-width` non-`auto`.
+ /// This yields a `MulticolFlow` with a single `MulticolColumnFlow` underneath it.
+ fn build_flow_for_multicol(&mut self, node: &ConcreteThreadSafeLayoutNode,
+ float_kind: Option<FloatKind>)
+ -> ConstructionResult {
+ let fragment = Fragment::new(node, SpecificFragmentInfo::Multicol);
+ let mut flow: FlowRef = Arc::new(MulticolFlow::from_fragment(fragment, float_kind));
+
+ let column_fragment = Fragment::new(node, SpecificFragmentInfo::MulticolColumn);
+ let column_flow = Arc::new(MulticolColumnFlow::from_fragment(column_fragment));
+
+ // First populate the column flow with its children.
+ let construction_result = self.build_flow_for_block_like(column_flow, node);
+
+ let mut abs_descendants = AbsoluteDescendants::new();
+ let mut fixed_descendants = AbsoluteDescendants::new();
+
+ if let ConstructionResult::Flow(column_flow, column_abs_descendants) = construction_result {
+ flow.add_new_child(column_flow);
+ abs_descendants.push_descendants(column_abs_descendants);
+ }
+
+ // The flow is done.
+ flow.finish();
+ let contains_positioned_fragments = flow.contains_positioned_fragments();
+ if contains_positioned_fragments {
+ // This is the containing block for all the absolute descendants.
+ flow.set_absolute_descendants(abs_descendants);
+
+ abs_descendants = AbsoluteDescendants::new();
+
+ let is_fixed_positioned = flow.as_block().is_fixed();
+ let is_absolutely_positioned =
+ flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
+ if is_fixed_positioned {
+ // Send itself along with the other fixed descendants.
+ fixed_descendants.push(flow.clone());
+ } else if is_absolutely_positioned {
+ // This is now the only absolute flow in the subtree which hasn't yet
+ // reached its containing block.
+ abs_descendants.push(flow.clone());
+ }
+ }
+
+ ConstructionResult::Flow(flow, abs_descendants)
+ }
+
/// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with
/// possibly other `TableCaptionFlow`s or `TableFlow`s underneath it.
fn build_flow_for_table_wrapper(&mut self, node: &ConcreteThreadSafeLayoutNode, float_value: float::T)
@@ -1115,15 +1162,15 @@ impl<'a, 'ln, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'ln>>
// The flow is done.
wrapper_flow.finish();
let contains_positioned_fragments = wrapper_flow.contains_positioned_fragments();
- let is_fixed_positioned = wrapper_flow.as_block().is_fixed();
- let is_absolutely_positioned =
- flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
if contains_positioned_fragments {
// This is the containing block for all the absolute descendants.
wrapper_flow.set_absolute_descendants(abs_descendants);
abs_descendants = AbsoluteDescendants::new();
+ let is_fixed_positioned = wrapper_flow.as_block().is_fixed();
+ let is_absolutely_positioned =
+ flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
if is_fixed_positioned {
// Send itself along with the other fixed descendants.
fixed_descendants.push(wrapper_flow.clone());