aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-05-02 19:12:09 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-05-02 19:12:09 -0700
commitfddf4ca30e7bc68c93a6f61e5a405aa9701cfc0f (patch)
treeb7e64a12ad440fa422e6fa97800a508f05c956d6
parentc74249aee5f1f3d13949ed8d88eb540276638006 (diff)
downloadservo-fddf4ca30e7bc68c93a6f61e5a405aa9701cfc0f.tar.gz
servo-fddf4ca30e7bc68c93a6f61e5a405aa9701cfc0f.zip
Update style of flow and remove its reliance on `tree`
`tree` is an old API that predates the use of traits. It should be redone. This commit breaks the dependency on it.
-rw-r--r--src/servo/layout/block.rs13
-rw-r--r--src/servo/layout/box_builder.rs44
-rw-r--r--src/servo/layout/flow.rs297
-rw-r--r--src/servo/layout/root.rs4
-rw-r--r--src/servo/layout/traverse.rs12
5 files changed, 223 insertions, 147 deletions
diff --git a/src/servo/layout/block.rs b/src/servo/layout/block.rs
index 130cc4da6ee..7b1fb67faa2 100644
--- a/src/servo/layout/block.rs
+++ b/src/servo/layout/block.rs
@@ -4,15 +4,14 @@
// Block layout.
-use core::cell::Cell;
-
use layout::box::{RenderBox};
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
-use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
+use layout::flow::{BlockFlow, FlowContext, InlineBlockFlow, RootFlow};
use layout::inline::InlineLayout;
use au = gfx::geometry;
+use core::cell::Cell;
use geom::point::Point2D;
use geom::rect::Rect;
use gfx::display_list::DisplayList;
@@ -82,7 +81,7 @@ impl BlockLayout for FlowContext {
let mut pref_width = Au(0);
/* find max width from child block contexts */
- for FlowTree.each_child(self) |child_ctx| {
+ for self.each_child |child_ctx| {
assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
min_width = au::max(min_width, child_ctx.d().min_width);
@@ -122,7 +121,7 @@ impl BlockLayout for FlowContext {
remaining_width -= left_used.add(&right_used);
}
- for FlowTree.each_child(self) |child_ctx| {
+ for self.each_child |child_ctx| {
assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
child_ctx.d().position.origin.x = left_used;
child_ctx.d().position.size.width = remaining_width;
@@ -134,7 +133,7 @@ impl BlockLayout for FlowContext {
let mut cur_y = Au(0);
- for FlowTree.each_child(self) |child_ctx| {
+ for self.each_child |child_ctx| {
child_ctx.d().position.origin.y = cur_y;
cur_y += child_ctx.d().position.size.height;
}
@@ -164,7 +163,7 @@ impl BlockLayout for FlowContext {
// TODO: handle any out-of-flow elements
// go deeper into the flow tree
- for FlowTree.each_child(self) |child| {
+ for self.each_child |child| {
self.build_display_list_for_child(builder, child, dirty, offset, list)
}
}
diff --git a/src/servo/layout/box_builder.rs b/src/servo/layout/box_builder.rs
index edaeaf5c00e..f127efa03e7 100644
--- a/src/servo/layout/box_builder.rs
+++ b/src/servo/layout/box_builder.rs
@@ -14,7 +14,6 @@ use layout::debug::{BoxedMutDebugMethods, DebugMethods};
use layout::flow::*;
use layout::inline::{InlineFlowData, InlineLayout};
use layout::root::RootFlowData;
-use util::tree;
use gfx::image::holder::ImageHolder;
use servo_util::range::Range;
@@ -223,9 +222,8 @@ impl BuilderContext {
priv fn attach_child_flow(&self, child: @mut FlowContext) {
let d = self.default_collector.flow.d(); // FIXME: borrow checker workaround
let cd = child.d(); // FIXME: borrow checker workaround
- debug!("BuilderContext: Adding child flow f%? of f%?",
- d.id, cd.id);
- tree::add_child(&FlowTree, self.default_collector.flow, child);
+ debug!("BuilderContext: Adding child flow f%? of f%?", d.id, cd.id);
+ self.default_collector.flow.add_child(child);
}
priv fn create_child_flow_of_type(&self,
@@ -332,10 +330,10 @@ pub impl LayoutTreeBuilder {
// eventually be elided or split, but the mapping between
// nodes and FlowContexts should not change during layout.
let flow = &mut this_ctx.default_collector.flow;
- for tree::each_child(&FlowTree, flow) |child_flow: &@mut FlowContext| {
+ for flow.each_child |child_flow: @mut FlowContext| {
let node = child_flow.d().node;
assert!(node.has_layout_data());
- node.layout_data().flow = Some(*child_flow);
+ node.layout_data().flow = Some(child_flow);
}
}
@@ -355,8 +353,8 @@ pub impl LayoutTreeBuilder {
let mut found_child_block = false;
let flow = &mut parent_ctx.default_collector.flow;
- for tree::each_child(&FlowTree, flow) |child_ctx: &@mut FlowContext| {
- match **child_ctx {
+ for flow.each_child |child_ctx: @mut FlowContext| {
+ match *child_ctx {
InlineFlow(*) | InlineBlockFlow(*) => found_child_inline = true,
BlockFlow(*) => found_child_block = true,
_ => {}
@@ -371,24 +369,36 @@ pub impl LayoutTreeBuilder {
// FIXME: this will create refcounted cycles between the removed flow and any
// of its RenderBox or FlowContext children, and possibly keep alive other junk
let parent_flow = parent_ctx.default_collector.flow;
+
+ // FIXME: Workaround for the borrow check.
+ let (first_child, last_child) = {
+ let parent_flow: &mut FlowContext = parent_flow;
+ let parent_flow_data = parent_flow.d();
+ (parent_flow_data.first_child, parent_flow_data.last_child)
+ };
+
// check first/last child for whitespace-ness
- for tree::first_child(&FlowTree, &parent_flow).each |first_flow: &@mut FlowContext| {
+ for first_child.each |first_flow: &@mut FlowContext| {
if first_flow.starts_inline_flow() {
let boxes = &mut first_flow.inline().boxes;
if boxes.len() == 1 && boxes[0].is_whitespace_only() {
- debug!("LayoutTreeBuilder: pruning whitespace-only first child flow f%d from parent f%d",
- first_flow.d().id, parent_flow.d().id);
- tree::remove_child(&FlowTree, parent_flow, *first_flow);
+ debug!("LayoutTreeBuilder: pruning whitespace-only first child flow \
+ f%d from parent f%d",
+ first_flow.d().id,
+ parent_flow.d().id);
+ parent_flow.remove_child(*first_flow);
}
}
}
- for tree::last_child(&FlowTree, &parent_flow).each |last_flow: &@mut FlowContext| {
+ for last_child.each |last_flow: &@mut FlowContext| {
if last_flow.starts_inline_flow() {
let boxes = &mut last_flow.inline().boxes;
if boxes.len() == 1 && boxes.last().is_whitespace_only() {
- debug!("LayoutTreeBuilder: pruning whitespace-only last child flow f%d from parent f%d",
- last_flow.d().id, parent_flow.d().id);
- tree::remove_child(&FlowTree, parent_flow, *last_flow);
+ debug!("LayoutTreeBuilder: pruning whitespace-only last child flow \
+ f%d from parent f%d",
+ last_flow.d().id,
+ parent_flow.d().id);
+ parent_flow.remove_child(*last_flow);
}
}
}
@@ -416,7 +426,7 @@ pub impl LayoutTreeBuilder {
}
fn make_flow(&mut self, ty: FlowContextType, node: AbstractNode) -> @mut FlowContext {
- let data = FlowData(self.next_flow_id(), node);
+ let data = FlowData::new(self.next_flow_id(), node);
let ret = match ty {
Flow_Absolute => @mut AbsoluteFlow(data),
Flow_Block => @mut BlockFlow(data, BlockFlowData()),
diff --git a/src/servo/layout/flow.rs b/src/servo/layout/flow.rs
index a4ea3965a7b..701136c2db2 100644
--- a/src/servo/layout/flow.rs
+++ b/src/servo/layout/flow.rs
@@ -2,8 +2,28 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use core;
-use core::cell::Cell;
+//! Servo's experimental layout system builds a tree of `FlowContext` and `RenderBox` objects and
+/// solves layout constraints to obtain positions and display attributes of tree nodes. Positions
+/// are computed in several tree traversals driven by the fundamental data dependencies required by
+/// inline and block layout.
+///
+/// Flows are interior nodes in the layout tree and correspond closely to *flow contexts* in the
+/// CSS specification. Flows are responsible for positioning their child flow contexts and render
+/// boxes. Flows have purpose-specific fields, such as auxiliary line box structs, out-of-flow
+/// child lists, and so on.
+///
+/// Currently, the important types of flows are:
+///
+/// * `BlockFlow`: a flow that establishes a block context. It has several child flows, each of
+/// which are positioned according to block formatting context rules (CSS block boxes). Block
+/// flows also contain a single `GenericBox` to represent their rendered borders, padding, etc.
+/// (In the future, this render box may be folded into `BlockFlow` to save space.)
+///
+/// * `InlineFlow`: a flow that establishes an inline context. It has a flat list of child
+/// boxes/flows that are subject to inline layout and line breaking and structs to represent
+/// line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
+/// similar methods.
+
use dom::node::AbstractNode;
use layout::block::{BlockFlowData, BlockLayout};
use layout::box::RenderBox;
@@ -12,41 +32,16 @@ use layout::debug::BoxedMutDebugMethods;
use layout::display_list_builder::DisplayListBuilder;
use layout::inline::{InlineFlowData, InlineLayout};
use layout::root::{RootFlowData, RootLayout};
-use util::tree;
-use geom::rect::Rect;
+
+use core::cell::Cell;
+use core::ptr;
use geom::point::Point2D;
+use geom::rect::Rect;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
-/** Servo's experimental layout system builds a tree of FlowContexts
-and RenderBoxes, and figures out positions and display attributes of
-tree nodes. Positions are computed in several tree traversals driven
-by fundamental data dependencies of inline and block layout.
-
-Flows are interior nodes in the layout tree, and correspond closely to
-flow contexts in the CSS specification. Flows are responsible for
-positioning their child flow contexts and render boxes. Flows have
-purpose-specific fields, such as auxilliary line box structs,
-out-of-flow child lists, and so on.
-
-Currently, the important types of flows are:
-
- * BlockFlow: a flow that establishes a block context. It has several
- child flows, each of which are positioned according to block
- formatting context rules (as if child flows CSS block boxes). Block
- flows also contain a single GenericBox to represent their rendered
- borders, padding, etc. (In the future, this render box may be
- folded into BlockFlow to save space.)
-
- * InlineFlow: a flow that establishes an inline context. It has a
- flat list of child boxes/flows that are subject to inline layout
- and line breaking, and structs to represent line breaks and mapping
- to CSS boxes, for the purpose of handling `getClientRects()`.
-
-*/
-
-/* The type of the formatting context, and data specific to each
-context, such as linebox structures or float lists */
+/// The type of the formatting context and data specific to each context, such as line box
+/// structures or float lists.
pub enum FlowContext {
AbsoluteFlow(FlowData),
BlockFlow(FlowData, BlockFlowData),
@@ -71,8 +66,13 @@ pub enum FlowContextType {
render boxes within the context. */
pub struct FlowData {
node: AbstractNode,
- /* reference to parent, children flow contexts */
- tree: tree::Tree<@mut FlowContext>,
+
+ parent: Option<@mut FlowContext>,
+ first_child: Option<@mut FlowContext>,
+ last_child: Option<@mut FlowContext>,
+ prev_sibling: Option<@mut FlowContext>,
+ next_sibling: Option<@mut FlowContext>,
+
/* TODO (Issue #87): debug only */
id: int,
@@ -84,55 +84,131 @@ pub struct FlowData {
position: Rect<Au>,
}
-pub fn FlowData(id: int, node: AbstractNode) -> FlowData {
- FlowData {
- node: node,
- tree: tree::empty(),
- id: id,
+impl FlowData {
+ pub fn new(id: int, node: AbstractNode) -> FlowData {
+ FlowData {
+ node: node,
+
+ parent: None,
+ first_child: None,
+ last_child: None,
+ prev_sibling: None,
+ next_sibling: None,
+
+ id: id,
- min_width: Au(0),
- pref_width: Au(0),
- position: Au::zero_rect()
+ min_width: Au(0),
+ pref_width: Au(0),
+ position: Au::zero_rect(),
+ }
}
}
-pub impl<'self> FlowContext {
- fn d(&'self mut self) -> &'self mut FlowData {
- unsafe {
- match *self {
- AbsoluteFlow(ref d) => cast::transmute(d),
- BlockFlow(ref d, _) => cast::transmute(d),
- FloatFlow(ref d) => cast::transmute(d),
- InlineBlockFlow(ref d) => cast::transmute(d),
- InlineFlow(ref d, _) => cast::transmute(d),
- RootFlow(ref d, _) => cast::transmute(d),
- TableFlow(ref d) => cast::transmute(d)
+impl<'self> FlowContext {
+ pub fn d(&'self mut self) -> &'self mut FlowData {
+ unsafe {
+ match *self {
+ AbsoluteFlow(ref d) => cast::transmute(d),
+ BlockFlow(ref d, _) => cast::transmute(d),
+ FloatFlow(ref d) => cast::transmute(d),
+ InlineBlockFlow(ref d) => cast::transmute(d),
+ InlineFlow(ref d, _) => cast::transmute(d),
+ RootFlow(ref d, _) => cast::transmute(d),
+ TableFlow(ref d) => cast::transmute(d)
+ }
+ }
+ }
+
+ /// Iterates over the immediate children of this flow.
+ ///
+ /// TODO: Fold me into `util::tree`.
+ pub fn each_child(@mut self, f: &fn(@mut FlowContext) -> bool) {
+ let mut current_opt = self.d().first_child;
+ while !current_opt.is_none() {
+ let current = current_opt.get();
+ if !f(current) {
+ break;
+ }
+ current_opt = current.d().next_sibling;
}
- }
}
- fn inline(&'self mut self) -> &'self mut InlineFlowData {
+ /// Adds the given flow to the end of the list of this flow's children. The new child must be
+ /// detached from the tree before calling this method.
+ ///
+ /// TODO: Fold me into `util::tree`.
+ pub fn add_child(@mut self, child: @mut FlowContext) {
+ let self_data = self.d(), child_data = child.d();
+
+ assert!(child_data.parent.is_none());
+ assert!(child_data.prev_sibling.is_none());
+ assert!(child_data.next_sibling.is_none());
+
+ match self_data.last_child {
+ None => {
+ self_data.first_child = Some(child);
+ }
+ Some(last_child) => {
+ assert!(last_child.d().next_sibling.is_none());
+ last_child.d().next_sibling = Some(child);
+ child_data.prev_sibling = Some(last_child);
+ }
+ }
+
+ self_data.last_child = Some(child);
+ child_data.parent = Some(self);
+ }
+
+ /// Removes the given flow from the tree.
+ ///
+ /// TODO: Fold me into `util::tree`.
+ pub fn remove_child(@mut self, child: @mut FlowContext) {
+ let self_data = self.d(), child_data = child.d();
+
+ assert!(child_data.parent.is_some());
+ assert!(ptr::ref_eq(&*child_data.parent.get(), self));
+
+ match child_data.prev_sibling {
+ None => self_data.first_child = child_data.next_sibling,
+ Some(prev_sibling) => {
+ prev_sibling.d().next_sibling = child_data.next_sibling;
+ child_data.prev_sibling = None;
+ }
+ }
+
+ match child_data.next_sibling {
+ None => self_data.last_child = child.d().prev_sibling,
+ Some(next_sibling) => {
+ next_sibling.d().prev_sibling = Some(next_sibling);
+ child_data.next_sibling = None;
+ }
+ }
+
+ child_data.parent = None;
+ }
+
+ pub fn inline(&'self mut self) -> &'self mut InlineFlowData {
match self {
&InlineFlow(_, ref i) => unsafe { cast::transmute(i) },
_ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id))
}
}
- fn block(&'self mut self) -> &'self mut BlockFlowData {
+ pub fn block(&'self mut self) -> &'self mut BlockFlowData {
match self {
&BlockFlow(_, ref mut b) => unsafe { cast::transmute(b) },
_ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id))
}
}
- fn root(&'self mut self) -> &'self mut RootFlowData {
+ pub fn root(&'self mut self) -> &'self mut RootFlowData {
match self {
&RootFlow(_, ref r) => unsafe { cast::transmute(r) },
_ => fail!(fmt!("Tried to access root data of non-root: f%d", self.d().id))
}
}
- fn bubble_widths(@mut self, ctx: &mut LayoutContext) {
+ pub fn bubble_widths(@mut self, ctx: &mut LayoutContext) {
match self {
@BlockFlow(*) => self.bubble_widths_block(ctx),
@InlineFlow(*) => self.bubble_widths_inline(ctx),
@@ -141,7 +217,7 @@ pub impl<'self> FlowContext {
}
}
- fn assign_widths(@mut self, ctx: &mut LayoutContext) {
+ pub fn assign_widths(@mut self, ctx: &mut LayoutContext) {
match self {
@BlockFlow(*) => self.assign_widths_block(ctx),
@InlineFlow(*) => self.assign_widths_inline(ctx),
@@ -150,7 +226,7 @@ pub impl<'self> FlowContext {
}
}
- fn assign_height(@mut self, ctx: &mut LayoutContext) {
+ pub fn assign_height(@mut self, ctx: &mut LayoutContext) {
match self {
@BlockFlow(*) => self.assign_height_block(ctx),
@InlineFlow(*) => self.assign_height_inline(ctx),
@@ -159,8 +235,11 @@ pub impl<'self> FlowContext {
}
}
- fn build_display_list_recurse(@mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
- offset: &Point2D<Au>, list: &Cell<DisplayList>) {
+ pub fn build_display_list_recurse(@mut self,
+ builder: &DisplayListBuilder,
+ dirty: &Rect<Au>,
+ offset: &Point2D<Au>,
+ list: &Cell<DisplayList>) {
let d = self.d(); // FIXME: borrow checker workaround
debug!("FlowContext::build_display_list at %?: %s", d.position, self.debug_str());
@@ -173,9 +252,10 @@ pub impl<'self> FlowContext {
}
// Actual methods that do not require much flow-specific logic
- fn foldl_all_boxes<B: Copy>(&mut self,
- seed: B,
- cb: &fn(a: B, b: @mut RenderBox) -> B) -> B {
+ pub fn foldl_all_boxes<B:Copy>(&mut self,
+ seed: B,
+ cb: &fn(a: B, b: @mut RenderBox) -> B)
+ -> B {
match self {
&RootFlow(*) => {
let root = self.root(); // FIXME: borrow checker workaround
@@ -193,85 +273,67 @@ pub impl<'self> FlowContext {
}
}
- fn foldl_boxes_for_node<B: Copy>(&mut self,
- node: AbstractNode,
- seed: B,
- cb: &fn(a: B,@mut RenderBox) -> B)
- -> B {
+ pub fn foldl_boxes_for_node<B:Copy>(&mut self,
+ node: AbstractNode,
+ seed: B,
+ cb: &fn(a: B, @mut RenderBox) -> B)
+ -> B {
do self.foldl_all_boxes(seed) |acc, box| {
if box.d().node == node { cb(acc, box) }
else { acc }
}
}
- fn iter_all_boxes<T>(&mut self, cb: &fn(@mut RenderBox) -> T) {
+ pub fn iter_all_boxes(&mut self, cb: &fn(@mut RenderBox) -> bool) {
match self {
&RootFlow(*) => {
let root = self.root(); // FIXME: borrow checker workaround
- for root.box.each |box| { cb(*box); }
+ for root.box.each |box| {
+ if !cb(*box) {
+ break;
+ }
+ }
}
&BlockFlow(*) => {
let block = self.block(); // FIXME: borrow checker workaround
- for block.box.each |box| { cb(*box); }
+ for block.box.each |box| {
+ if !cb(*box) {
+ break;
+ }
+ }
}
&InlineFlow(*) => {
let inline = self.inline(); // FIXME: borrow checker workaround
- for inline.boxes.each |box| { cb(*box); }
+ for inline.boxes.each |box| {
+ if !cb(*box) {
+ break;
+ }
+ }
}
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
}
}
- fn iter_boxes_for_node<T>(&mut self,
- node: AbstractNode,
- cb: &fn(@mut RenderBox) -> T) {
- do self.iter_all_boxes |box| {
- if box.d().node == node { cb(box); }
+ pub fn iter_boxes_for_node(&mut self, node: AbstractNode, cb: &fn(@mut RenderBox) -> bool) {
+ for self.iter_all_boxes |box| {
+ if box.d().node == node {
+ if !cb(box) {
+ break;
+ }
+ }
}
}
}
-/* The tree holding FlowContexts */
-pub enum FlowTree { FlowTree }
-
-impl FlowTree {
- fn each_child(&self, ctx: @mut FlowContext, f: &fn(box: @mut FlowContext) -> bool) {
- tree::each_child(self, &ctx, |box| f(*box) )
- }
-}
-
-impl tree::ReadMethods<@mut FlowContext> for FlowTree {
- fn with_tree_fields<R>(&self, box: &@mut FlowContext, f: &fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
- let tree = &mut box.d().tree;
- f(tree)
- }
-}
-
-impl FlowTree {
- fn add_child(self, parent: @mut FlowContext, child: @mut FlowContext) {
- tree::add_child(&self, parent, child)
- }
-}
-
-impl tree::WriteMethods<@mut FlowContext> for FlowTree {
- fn tree_eq(&self, a: &@mut FlowContext, b: &@mut FlowContext) -> bool { core::managed::mut_ptr_eq(*a, *b) }
-
- fn with_tree_fields<R>(&self, box: &@mut FlowContext, f: &fn(&mut tree::Tree<@mut FlowContext>) -> R) -> R {
- let tree = &mut box.d().tree;
- f(tree)
- }
-}
-
-
impl BoxedMutDebugMethods for FlowContext {
fn dump(@mut self) {
- self.dump_indent(0u);
+ self.dump_indent(0);
}
- /** Dumps the flow tree, for debugging, with indentation. */
+ /// Dumps the flow tree, for debugging, with indentation.
fn dump_indent(@mut self, indent: uint) {
let mut s = ~"|";
- for uint::range(0u, indent) |_i| {
+ for uint::range(0, indent) |_i| {
s += ~"---- ";
}
@@ -279,8 +341,8 @@ impl BoxedMutDebugMethods for FlowContext {
debug!("%s", s);
// FIXME: this should have a pure/const version?
- for FlowTree.each_child(self) |child| {
- child.dump_indent(indent + 1u)
+ for self.each_child |child| {
+ child.dump_indent(indent + 1)
}
}
@@ -313,3 +375,4 @@ impl BoxedMutDebugMethods for FlowContext {
fmt!("f%? %?", d.id, repr)
}
}
+
diff --git a/src/servo/layout/root.rs b/src/servo/layout/root.rs
index 98e1e49565b..af92b037d78 100644
--- a/src/servo/layout/root.rs
+++ b/src/servo/layout/root.rs
@@ -10,7 +10,7 @@ use gfx::geometry::Au;
use layout::block::BlockLayout;
use layout::box::RenderBox;
use layout::context::LayoutContext;
-use layout::flow::{FlowContext, FlowTree, RootFlow};
+use layout::flow::{FlowContext, RootFlow};
use layout::display_list_builder::DisplayListBuilder;
pub struct RootFlowData {
@@ -63,7 +63,7 @@ impl RootLayout for FlowContext {
// the root adjusts self height to at least cover the viewport.
let mut cur_y = Au(0);
- for FlowTree.each_child(self) |child_ctx| {
+ for self.each_child |child_ctx| {
child_ctx.d().position.origin.y = cur_y;
cur_y += child_ctx.d().position.size.height;
}
diff --git a/src/servo/layout/traverse.rs b/src/servo/layout/traverse.rs
index 5d8e323ae17..b4710b974bc 100644
--- a/src/servo/layout/traverse.rs
+++ b/src/servo/layout/traverse.rs
@@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use layout::flow::{FlowContext, FlowTree};
+use layout::flow::FlowContext;
-/** Trait for running tree-based traversals over layout contexts */
+/// A trait for running tree-based traversals over flows contexts.
pub trait FlowContextTraversals {
fn traverse_preorder(@mut self, preorder_cb: &fn(@mut FlowContext));
fn traverse_postorder(@mut self, postorder_cb: &fn(@mut FlowContext));
@@ -13,11 +13,15 @@ pub trait FlowContextTraversals {
impl FlowContextTraversals for FlowContext {
fn traverse_preorder(@mut self, preorder_cb: &fn(@mut FlowContext)) {
preorder_cb(self);
- do FlowTree.each_child(self) |child| { child.traverse_preorder(preorder_cb); true }
+ for self.each_child |child| {
+ child.traverse_preorder(preorder_cb);
+ }
}
fn traverse_postorder(@mut self, postorder_cb: &fn(@mut FlowContext)) {
- do FlowTree.each_child(self) |child| { child.traverse_postorder(postorder_cb); true }
+ for self.each_child |child| {
+ child.traverse_postorder(postorder_cb);
+ }
postorder_cb(self);
}
}