aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/block.rs10
-rw-r--r--components/layout/flow.rs109
-rw-r--r--components/layout/generated_content.rs2
-rw-r--r--components/layout/inline.rs8
-rw-r--r--components/layout/parallel.rs8
-rw-r--r--components/layout/sequential.rs13
-rw-r--r--components/layout/traversal.rs87
-rw-r--r--components/layout_thread/lib.rs9
8 files changed, 107 insertions, 139 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 9bd413a2725..c677c9b659f 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -36,9 +36,8 @@ use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, INLINE_POSITION_IS_STATIC};
-use flow::{FragmentationContext, MARGINS_CANNOT_COLLAPSE, PreorderFlowTraversal};
-use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow};
-use flow::IS_ABSOLUTELY_POSITIONED;
+use flow::{IS_ABSOLUTELY_POSITIONED, FragmentationContext, MARGINS_CANNOT_COLLAPSE};
+use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow};
use flow_list::FlowList;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM};
@@ -60,6 +59,7 @@ use style::properties::ComputedValues;
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION};
use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage};
use style::values::computed::LengthOrPercentageOrAuto;
+use traversal::PreorderFlowTraversal;
/// Information specific to floated blocks.
#[derive(Clone, Serialize)]
@@ -1065,8 +1065,8 @@ impl BlockFlow {
// Assign block-sizes for all flows in this absolute flow tree.
// This is preorder because the block-size of an absolute flow may depend on
// the block-size of its containing block, which may also be an absolute flow.
- (&mut *self as &mut Flow).traverse_preorder_absolute_flows(
- &mut AbsoluteAssignBSizesTraversal(layout_context.shared_context()));
+ let assign_abs_b_sizes = AbsoluteAssignBSizesTraversal(layout_context.shared_context());
+ assign_abs_b_sizes.traverse_absolute_flows(&mut *self);
}
// Don't remove the dirty bits yet if we're absolutely-positioned, since our final size
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index c6fc65407e5..e2d4e5cd99c 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -535,28 +535,6 @@ pub trait ImmutableFlowUtils {
}
pub trait MutableFlowUtils {
- // Traversals
-
- /// Traverses the tree in preorder.
- fn traverse_preorder<T: PreorderFlowTraversal>(self, traversal: &T);
-
- /// Traverses the tree in postorder.
- fn traverse_postorder<T: PostorderFlowTraversal>(self, traversal: &T);
-
- /// Traverses the tree in-order.
- fn traverse_inorder<T: InorderFlowTraversal>(self, traversal: &mut T, level: u32);
-
- /// Traverse the Absolute flow tree in preorder.
- ///
- /// Traverse all your direct absolute descendants, who will then traverse
- /// their direct absolute descendants.
- ///
- /// Return true if the traversal is to continue or false to stop.
- fn traverse_preorder_absolute_flows<T>(&mut self, traversal: &mut T)
- where T: PreorderFlowTraversal;
-
- // Mutators
-
/// 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: &::ServoArc<ComputedValues>);
@@ -608,42 +586,6 @@ impl FlowClass {
}
}
-/// A top-down traversal.
-pub trait PreorderFlowTraversal {
- /// The operation to perform. Return true to continue or false to stop.
- fn process(&self, flow: &mut Flow);
-
- /// Returns true if this node must be processed in-order. If this returns false,
- /// we skip the operation for this node, but continue processing the descendants.
- /// This is called *after* parent nodes are visited.
- fn should_process(&self, _flow: &mut Flow) -> bool {
- true
- }
-}
-
-/// A bottom-up traversal, with a optional in-order pass.
-pub trait PostorderFlowTraversal {
- /// The operation to perform. Return true to continue or false to stop.
- fn process(&self, flow: &mut Flow);
-
- /// Returns false if this node must be processed in-order. If this returns false, we skip the
- /// operation for this node, but continue processing the ancestors. This is called *after*
- /// child nodes are visited.
- fn should_process(&self, _flow: &mut Flow) -> bool {
- true
- }
-}
-
-/// An in-order (sequential only) traversal.
-pub trait InorderFlowTraversal {
- /// The operation to perform. Returns the level of the tree we're at.
- fn process(&mut self, flow: &mut Flow, level: u32);
-
- /// Returns true if this node should be processed and false if neither this node nor its
- /// descendants should be processed.
- fn should_process_subtree(&mut self, flow: &mut Flow) -> bool;
-}
-
bitflags! {
#[doc = "Flags used in flows."]
pub flags FlowFlags: u32 {
@@ -1354,41 +1296,6 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
}
impl<'a> MutableFlowUtils for &'a mut Flow {
- /// Traverses the tree in preorder.
- fn traverse_preorder<T: PreorderFlowTraversal>(self, traversal: &T) {
- if traversal.should_process(self) {
- traversal.process(self);
- }
-
- for kid in child_iter_mut(self) {
- kid.traverse_preorder(traversal);
- }
- }
-
- /// Traverses the tree in postorder.
- fn traverse_postorder<T: PostorderFlowTraversal>(self, traversal: &T) {
- for kid in child_iter_mut(self) {
- kid.traverse_postorder(traversal);
- }
-
- if traversal.should_process(self) {
- traversal.process(self)
- }
- }
-
- /// Traverses the tree in-order.
- fn traverse_inorder<T: InorderFlowTraversal>(self, traversal: &mut T, level: u32) {
- if !traversal.should_process_subtree(self) {
- return;
- }
-
- traversal.process(self, level);
-
- for kid in child_iter_mut(self) {
- kid.traverse_inorder(traversal, level + 1);
- }
- }
-
/// 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: &::ServoArc<ComputedValues>) {
@@ -1396,22 +1303,6 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
mut_base(self).update_flags_if_needed(style);
self.bubble_inline_sizes();
}
-
- /// Traverse the Absolute flow tree in preorder.
- ///
- /// Traverse all your direct absolute descendants, who will then traverse
- /// their direct absolute descendants.
- ///
- /// Return true if the traversal is to continue or false to stop.
- fn traverse_preorder_absolute_flows<T>(&mut self, traversal: &mut T)
- where T: PreorderFlowTraversal {
- traversal.process(*self);
-
- let descendant_offset_iter = mut_base(*self).abs_descendants.iter();
- for ref mut descendant_link in descendant_offset_iter {
- descendant_link.traverse_preorder_absolute_flows(traversal)
- }
- }
}
impl MutableOwnedFlowUtils for FlowRef {
diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs
index 26e1754fad9..d9adfabb832 100644
--- a/components/layout/generated_content.rs
+++ b/components/layout/generated_content.rs
@@ -10,7 +10,6 @@
use context::{LayoutContext, with_thread_local_font_context};
use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils};
-use flow::InorderFlowTraversal;
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::display_list::OpaqueNode;
use script_layout_interface::wrapper_traits::PseudoElementType;
@@ -22,6 +21,7 @@ use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
use text::TextRunScanner;
+use traversal::InorderFlowTraversal;
// Decimal styles per CSS-COUNTER-STYLES § 6.1:
static DECIMAL: [char; 10] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index d6c561de22a..bcda03232c8 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -12,8 +12,7 @@ use display_list_builder::{DisplayListBuildState, InlineFlowDisplayListBuilding}
use euclid::{Point2D, Size2D};
use floats::{FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
-use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, EarlyAbsolutePositionInfo, MutableFlowUtils};
-use flow::OpaqueFlow;
+use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, EarlyAbsolutePositionInfo, OpaqueFlow};
use flow_ref::FlowRef;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::IS_ELLIPSIS;
@@ -36,6 +35,7 @@ use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::{longhands, ComputedValues};
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPOSITION, RESOLVE_GENERATED_CONTENT};
use text;
+use traversal::PreorderFlowTraversal;
use unicode_bidi as bidi;
/// `Line`s are represented as offsets into the child list, rather than
@@ -1490,8 +1490,8 @@ impl Flow for InlineFlow {
// Assign block-sizes for all flows in this absolute flow tree.
// This is preorder because the block-size of an absolute flow may depend on
// the block-size of its containing block, which may also be an absolute flow.
- (&mut *self as &mut Flow).traverse_preorder_absolute_flows(
- &mut AbsoluteAssignBSizesTraversal(layout_context.shared_context()));
+ let assign_abs_b_sizes = AbsoluteAssignBSizesTraversal(layout_context.shared_context());
+ assign_abs_b_sizes.traverse_absolute_flows(&mut *self);
}
self.base.position.size.block = match self.last_line_containing_real_fragments() {
diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs
index bdc178b74c4..e1753d11803 100644
--- a/components/layout/parallel.rs
+++ b/components/layout/parallel.rs
@@ -9,7 +9,7 @@
#![allow(unsafe_code)]
use context::LayoutContext;
-use flow::{self, Flow, MutableFlowUtils, PostorderFlowTraversal, PreorderFlowTraversal};
+use flow::{self, Flow};
use flow_ref::FlowRef;
use profile_traits::time::{self, TimerMetadata, profile};
use rayon;
@@ -18,8 +18,8 @@ use smallvec::SmallVec;
use std::mem;
use std::sync::atomic::{AtomicIsize, Ordering};
use style::dom::UnsafeNode;
-use traversal::{AssignISizes, BubbleISizes};
-use traversal::AssignBSizes;
+use traversal::{AssignBSizes, AssignISizes, BubbleISizes};
+use traversal::{PostorderFlowTraversal, PreorderFlowTraversal};
pub use style::parallel::traverse_dom;
@@ -195,7 +195,7 @@ pub fn traverse_flow_tree_preorder(
queue: &rayon::ThreadPool) {
if opts::get().bubble_inline_sizes_separately {
let bubble_inline_sizes = BubbleISizes { layout_context: &context };
- root.traverse_postorder(&bubble_inline_sizes);
+ bubble_inline_sizes.traverse(root);
}
let assign_isize_traversal = &AssignISizes { layout_context: &context };
diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs
index b97f0a4d357..9e6ea4c2fe6 100644
--- a/components/layout/sequential.rs
+++ b/components/layout/sequential.rs
@@ -9,21 +9,19 @@ use context::LayoutContext;
use display_list_builder::DisplayListBuildState;
use euclid::{Point2D, Vector2D};
use floats::SpeculatedFloatPlacement;
-use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils};
-use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
-use flow::IS_ABSOLUTELY_POSITIONED;
+use flow::{self, Flow, ImmutableFlowUtils, IS_ABSOLUTELY_POSITIONED};
use fragment::{FragmentBorderBoxIterator, CoordinateSystem};
use generated_content::ResolveGeneratedContent;
use incremental::RelayoutMode;
use servo_config::opts;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, STORE_OVERFLOW};
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
+use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal};
pub use style::sequential::traverse_dom;
pub fn resolve_generated_content(root: &mut Flow, layout_context: &LayoutContext) {
- let mut traversal = ResolveGeneratedContent::new(&layout_context);
- root.traverse_inorder(&mut traversal, 0);
+ ResolveGeneratedContent::new(&layout_context).traverse(root, 0);
}
pub fn traverse_flow_tree_preorder(root: &mut Flow, layout_context: &LayoutContext, relayout_mode: RelayoutMode) {
@@ -56,10 +54,7 @@ pub fn traverse_flow_tree_preorder(root: &mut Flow, layout_context: &LayoutConte
let bubble_inline_sizes = BubbleISizes {
layout_context: &layout_context,
};
- {
- let root: &mut Flow = root;
- root.traverse_postorder(&bubble_inline_sizes);
- }
+ bubble_inline_sizes.traverse(root);
}
let assign_inline_sizes = AssignISizes {
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index d31be602ee8..54e62b6d591 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -7,8 +7,7 @@
use construct::FlowConstructor;
use context::LayoutContext;
use display_list_builder::DisplayListBuildState;
-use flow::{self, PreorderFlowTraversal};
-use flow::{CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils, PostorderFlowTraversal};
+use flow::{self, CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use servo_config::opts;
use style::context::{SharedStyleContext, StyleContext};
@@ -92,6 +91,90 @@ impl<'a, E> DomTraversal<E> for RecalcStyleAndConstructFlows<'a>
}
}
+/// A top-down traversal.
+pub trait PreorderFlowTraversal {
+ /// The operation to perform. Return true to continue or false to stop.
+ fn process(&self, flow: &mut Flow);
+
+ /// Returns true if this node must be processed in-order. If this returns false,
+ /// we skip the operation for this node, but continue processing the descendants.
+ /// This is called *after* parent nodes are visited.
+ fn should_process(&self, _flow: &mut Flow) -> bool {
+ true
+ }
+
+ /// Traverses the tree in preorder.
+ fn traverse(&self, flow: &mut Flow) {
+ if self.should_process(flow) {
+ self.process(flow);
+ }
+ for kid in flow::child_iter_mut(flow) {
+ self.traverse(kid);
+ }
+ }
+
+ /// Traverse the Absolute flow tree in preorder.
+ ///
+ /// Traverse all your direct absolute descendants, who will then traverse
+ /// their direct absolute descendants.
+ ///
+ /// Return true if the traversal is to continue or false to stop.
+ fn traverse_absolute_flows(&self, flow: &mut Flow) {
+ if self.should_process(flow) {
+ self.process(flow);
+ }
+ for descendant_link in flow::mut_base(flow).abs_descendants.iter() {
+ self.traverse_absolute_flows(descendant_link)
+ }
+ }
+}
+
+/// A bottom-up traversal, with a optional in-order pass.
+pub trait PostorderFlowTraversal {
+ /// The operation to perform. Return true to continue or false to stop.
+ fn process(&self, flow: &mut Flow);
+
+ /// Returns false if this node must be processed in-order. If this returns false, we skip the
+ /// operation for this node, but continue processing the ancestors. This is called *after*
+ /// child nodes are visited.
+ fn should_process(&self, _flow: &mut Flow) -> bool {
+ true
+ }
+
+ /// Traverses the tree in postorder.
+ fn traverse(&self, flow: &mut Flow) {
+ for kid in flow::child_iter_mut(flow) {
+ self.traverse(kid);
+ }
+ if self.should_process(flow) {
+ self.process(flow);
+ }
+ }
+}
+
+/// An in-order (sequential only) traversal.
+pub trait InorderFlowTraversal {
+ /// The operation to perform. Returns the level of the tree we're at.
+ fn process(&mut self, flow: &mut Flow, level: u32);
+
+ /// Returns true if this node should be processed and false if neither this node nor its
+ /// descendants should be processed.
+ fn should_process_subtree(&mut self, _flow: &mut Flow) -> bool {
+ true
+ }
+
+ /// Traverses the tree in-order.
+ fn traverse(&mut self, flow: &mut Flow, level: u32) {
+ if !self.should_process_subtree(flow) {
+ return;
+ }
+ self.process(flow, level);
+ for kid in flow::child_iter_mut(flow) {
+ self.traverse(kid, level + 1);
+ }
+ }
+}
+
/// A bottom-up, parallelizable traversal.
pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> {
/// The operation to perform. Return true to continue or false to stop.
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index 8ee539d6f79..540ea92fd70 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -71,7 +71,7 @@ use layout::context::RegisteredPainter;
use layout::context::RegisteredPainters;
use layout::context::heap_size_of_persistent_local_context;
use layout::display_list_builder::ToGfxColor;
-use layout::flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
+use layout::flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow_ref::FlowRef;
use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT, RelayoutMode};
use layout::layout_debug;
@@ -82,7 +82,7 @@ use layout::query::{process_margin_style_query, process_node_overflow_request, p
use layout::query::{process_node_geometry_request, process_node_scroll_area_request};
use layout::query::{process_node_scroll_root_id_request, process_offset_parent_query};
use layout::sequential;
-use layout::traversal::{ComputeStackingRelativePositions, RecalcStyleAndConstructFlows};
+use layout::traversal::{ComputeStackingRelativePositions, PreorderFlowTraversal, RecalcStyleAndConstructFlows};
use layout::webrender_helpers::WebRenderDisplayListConverter;
use layout::wrapper::LayoutNodeLayoutData;
use layout_traits::LayoutThreadFactory;
@@ -975,9 +975,8 @@ impl LayoutThread {
flow::mut_base(layout_root).clip = data.page_clip_rect;
if flow::base(layout_root).restyle_damage.contains(REPOSITION) {
- layout_root.traverse_preorder(&ComputeStackingRelativePositions {
- layout_context: layout_context
- });
+ let traversal = ComputeStackingRelativePositions { layout_context: layout_context };
+ traversal.traverse(layout_root);
}
if flow::base(layout_root).restyle_damage.contains(REPAINT) ||