diff options
author | Jack Moffitt <jack@metajack.im> | 2013-12-20 22:04:46 -0700 |
---|---|---|
committer | Jack Moffitt <jack@metajack.im> | 2014-01-12 19:45:45 -0700 |
commit | a7ef1cd35e9347a285f245041db4eb94047f4ab0 (patch) | |
tree | a6dc269d9f3cb031d7ea096628c81b7edc971c1c /src/components/main/layout | |
parent | 728fb9a7dedf67445e7f12eafb314117efede70d (diff) | |
download | servo-a7ef1cd35e9347a285f245041db4eb94047f4ab0.tar.gz servo-a7ef1cd35e9347a285f245041db4eb94047f4ab0.zip |
Upgrade to latest Rust.
Diffstat (limited to 'src/components/main/layout')
-rw-r--r-- | src/components/main/layout/block.rs | 172 | ||||
-rw-r--r-- | src/components/main/layout/box_.rs (renamed from src/components/main/layout/box.rs) | 122 | ||||
-rw-r--r-- | src/components/main/layout/construct.rs | 63 | ||||
-rw-r--r-- | src/components/main/layout/display_list_builder.rs | 12 | ||||
-rw-r--r-- | src/components/main/layout/extra.rs | 28 | ||||
-rw-r--r-- | src/components/main/layout/float_context.rs | 46 | ||||
-rw-r--r-- | src/components/main/layout/flow.rs | 45 | ||||
-rw-r--r-- | src/components/main/layout/inline.rs | 78 | ||||
-rw-r--r-- | src/components/main/layout/layout_task.rs | 98 | ||||
-rw-r--r-- | src/components/main/layout/text.rs | 22 | ||||
-rw-r--r-- | src/components/main/layout/util.rs | 49 | ||||
-rw-r--r-- | src/components/main/layout/wrapper.rs | 72 |
12 files changed, 393 insertions, 414 deletions
diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index ff85f4e14ad..276e6a38e1d 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -4,7 +4,7 @@ //! CSS block formatting contexts. -use layout::box::Box; +use layout::box_::Box; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::flow::{BlockFlowClass, FlowClass, Flow, FlowData, ImmutableFlowUtils}; @@ -12,7 +12,7 @@ use layout::flow; use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified}; use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType}; -use std::cell::Cell; +use std::cell::RefCell; use geom::{Point2D, Rect, SideOffsets2D}; use gfx::display_list::DisplayList; use servo_util::geometry::Au; @@ -53,7 +53,7 @@ pub struct BlockFlow { base: FlowData, /// The associated box. - box: Option<Box>, + box_: Option<Box>, /// Whether this block flow is the root flow. is_root: bool, @@ -66,25 +66,25 @@ impl BlockFlow { pub fn new(base: FlowData) -> BlockFlow { BlockFlow { base: base, - box: None, + box_: None, is_root: false, float: None } } - pub fn from_box(base: FlowData, box: Box) -> BlockFlow { + pub fn from_box(base: FlowData, box_: Box) -> BlockFlow { BlockFlow { base: base, - box: Some(box), + box_: Some(box_), is_root: false, float: None } } - pub fn float_from_box(base: FlowData, float_type: FloatType, box: Box) -> BlockFlow { + pub fn float_from_box(base: FlowData, float_type: FloatType, box_: Box) -> BlockFlow { BlockFlow { base: base, - box: Some(box), + box_: Some(box_), is_root: false, float: Some(~FloatedBlockInfo::new(float_type)) } @@ -93,7 +93,7 @@ impl BlockFlow { pub fn new_root(base: FlowData) -> BlockFlow { BlockFlow { base: base, - box: None, + box_: None, is_root: true, float: None } @@ -102,7 +102,7 @@ impl BlockFlow { pub fn new_float(base: FlowData, float_type: FloatType) -> BlockFlow { BlockFlow { base: base, - box: None, + box_: None, is_root: false, float: Some(~FloatedBlockInfo::new(float_type)) } @@ -113,10 +113,10 @@ impl BlockFlow { } pub fn teardown(&mut self) { - for box in self.box.iter() { - box.teardown(); + for box_ in self.box_.iter() { + box_.teardown(); } - self.box = None; + self.box_ = None; self.float = None; } @@ -172,9 +172,9 @@ impl BlockFlow { (width_Au, left_margin_Au, right_margin_Au) } - fn compute_block_margins(&self, box: &Box, remaining_width: Au, available_width: Au) + fn compute_block_margins(&self, box_: &Box, remaining_width: Au, available_width: Au) -> (Au, Au, Au) { - let style = box.style(); + let style = box_.style(); let (width, maybe_margin_left, maybe_margin_right) = (MaybeAuto::from_style(style.Box.width, remaining_width), @@ -215,8 +215,8 @@ impl BlockFlow { return (width, margin_left, margin_right); } - fn compute_float_margins(&self, box: &Box, remaining_width: Au) -> (Au, Au, Au) { - let style = box.style(); + fn compute_float_margins(&self, box_: &Box, remaining_width: Au) -> (Au, Au, Au) { + let style = box_.style(); let margin_left = MaybeAuto::from_style(style.Margin.margin_left, remaining_width).specified_or_zero(); let margin_right = MaybeAuto::from_style(style.Margin.margin_right, @@ -240,20 +240,20 @@ impl BlockFlow { let mut left_offset = Au::new(0); let mut float_ctx = Invalid; - for box in self.box.iter() { - clearance = match box.clear() { + for box_ in self.box_.iter() { + clearance = match box_.clear() { None => Au::new(0), Some(clear) => { self.base.floats_in.clearance(clear) } }; - top_offset = clearance + box.margin.get().top + box.border.get().top + - box.padding.get().top; + top_offset = clearance + box_.margin.get().top + box_.border.get().top + + box_.padding.get().top; cur_y = cur_y + top_offset; - bottom_offset = box.margin.get().bottom + box.border.get().bottom + - box.padding.get().bottom; - left_offset = box.offset(); + bottom_offset = box_.margin.get().bottom + box_.border.get().bottom + + box_.padding.get().bottom; + left_offset = box_.offset(); } if inorder { @@ -279,17 +279,17 @@ impl BlockFlow { let mut top_margin_collapsible = false; let mut bottom_margin_collapsible = false; let mut first_in_flow = true; - for box in self.box.iter() { - if !self.is_root && box.border.get().top == Au(0) && box.padding.get().top == Au(0) { - collapsible = box.margin.get().top; + for box_ in self.box_.iter() { + if !self.is_root && box_.border.get().top == Au(0) && box_.padding.get().top == Au(0) { + collapsible = box_.margin.get().top; top_margin_collapsible = true; } - if !self.is_root && box.border.get().bottom == Au(0) && - box.padding.get().bottom == Au(0) { + if !self.is_root && box_.border.get().bottom == Au(0) && + box_.padding.get().bottom == Au(0) { bottom_margin_collapsible = true; } - margin_top = box.margin.get().top; - margin_bottom = box.margin.get().bottom; + margin_top = box_.margin.get().top; + margin_bottom = box_.margin.get().bottom; } for kid in self.base.child_iter() { @@ -332,8 +332,8 @@ impl BlockFlow { cur_y - top_offset - collapsing }; - for box in self.box.iter() { - let style = box.style(); + for box_ in self.box_.iter() { + let style = box_.style(); // At this point, `height` is the height of the containing block, so passing `height` // as the second argument here effectively makes percentages relative to the containing @@ -345,9 +345,9 @@ impl BlockFlow { } let mut noncontent_height = Au::new(0); - for box in self.box.iter() { - let mut position = box.position.get(); - let mut margin = box.margin.get(); + for box_ in self.box_.iter() { + let mut position = box_.position.get(); + let mut margin = box_.margin.get(); // The associated box is the border box of this flow. margin.top = margin_top; @@ -355,14 +355,14 @@ impl BlockFlow { position.origin.y = clearance + margin.top; - noncontent_height = box.padding.get().top + box.padding.get().bottom + - box.border.get().top + box.border.get().bottom; + noncontent_height = box_.padding.get().top + box_.padding.get().bottom + + box_.border.get().top + box_.border.get().bottom; position.size.height = height + noncontent_height; noncontent_height = noncontent_height + clearance + margin.top + margin.bottom; - box.position.set(position); - box.margin.set(margin); + box_.position.set(position); + box_.margin.set(margin); } self.base.position.size.height = height + noncontent_height; @@ -384,19 +384,19 @@ impl BlockFlow { let mut full_noncontent_width = Au(0); let mut margin_height = Au(0); - for box in self.box.iter() { - height = box.position.get().size.height; - clearance = match box.clear() { + for box_ in self.box_.iter() { + height = box_.position.get().size.height; + clearance = match box_.clear() { None => Au(0), Some(clear) => self.base.floats_in.clearance(clear), }; - let noncontent_width = box.padding.get().left + box.padding.get().right + - box.border.get().left + box.border.get().right; + let noncontent_width = box_.padding.get().left + box_.padding.get().right + + box_.border.get().left + box_.border.get().right; - full_noncontent_width = noncontent_width + box.margin.get().left + - box.margin.get().right; - margin_height = box.margin.get().top + box.margin.get().bottom; + full_noncontent_width = noncontent_width + box_.margin.get().left + + box_.margin.get().right; + margin_height = box_.margin.get().top + box_.margin.get().bottom; } let info = PlacementInfo { @@ -427,8 +427,8 @@ impl BlockFlow { let mut cur_y = Au(0); let mut top_offset = Au(0); - for box in self.box.iter() { - top_offset = box.margin.get().top + box.border.get().top + box.padding.get().top; + for box_ in self.box_.iter() { + top_offset = box_.margin.get().top + box_.border.get().top + box_.padding.get().top; cur_y = cur_y + top_offset; } @@ -441,31 +441,31 @@ impl BlockFlow { let mut height = cur_y - top_offset; let mut noncontent_height; - let box = self.box.as_ref().unwrap(); - let mut position = box.position.get(); + let box_ = self.box_.as_ref().unwrap(); + let mut position = box_.position.get(); // The associated box is the border box of this flow. - position.origin.y = box.margin.get().top; + position.origin.y = box_.margin.get().top; - noncontent_height = box.padding.get().top + box.padding.get().bottom + - box.border.get().top + box.border.get().bottom; + noncontent_height = box_.padding.get().top + box_.padding.get().bottom + + box_.border.get().top + box_.border.get().bottom; //TODO(eatkinson): compute heights properly using the 'height' property. - let height_prop = MaybeAuto::from_style(box.style().Box.height, + let height_prop = MaybeAuto::from_style(box_.style().Box.height, Au::new(0)).specified_or_zero(); height = geometry::max(height, height_prop) + noncontent_height; debug!("assign_height_float -- height: {}", height); position.size.height = height; - box.position.set(position); + box_.position.set(position); } pub fn build_display_list_block<E:ExtraDisplayListData>( &mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>, - list: &Cell<DisplayList<E>>) + list: &RefCell<DisplayList<E>>) -> bool { if self.is_float() { return self.build_display_list_float(builder, dirty, list); @@ -479,8 +479,8 @@ impl BlockFlow { debug!("build_display_list_block: adding display element"); // add box that starts block context - for box in self.box.iter() { - box.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list) + for box_ in self.box_.iter() { + box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list) } // TODO: handle any out-of-flow elements @@ -497,7 +497,7 @@ impl BlockFlow { &mut self, builder: &DisplayListBuilder, dirty: &Rect<Au>, - list: &Cell<DisplayList<E>>) + list: &RefCell<DisplayList<E>>) -> bool { let abs_rect = Rect(self.base.abs_position, self.base.position.size); if !abs_rect.intersects(dirty) { @@ -506,8 +506,8 @@ impl BlockFlow { let offset = self.base.abs_position + self.float.get_ref().rel_pos; // add box that starts block context - for box in self.box.iter() { - box.build_display_list(builder, dirty, offset, (&*self) as &Flow, list) + for box_ in self.box_.iter() { + box_.build_display_list(builder, dirty, offset, (&*self) as &Flow, list) } @@ -564,13 +564,13 @@ impl Flow for BlockFlow { /* if not an anonymous block context, add in block box's widths. these widths will not include child elements, just padding etc. */ - for box in self.box.iter() { + for box_ in self.box_.iter() { { // Can compute border width here since it doesn't depend on anything. - box.compute_borders(box.style()) + box_.compute_borders(box_.style()) } - let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths(); + let (this_minimum_width, this_preferred_width) = box_.minimum_and_preferred_widths(); min_width = min_width + this_minimum_width; pref_width = pref_width + this_preferred_width; } @@ -612,17 +612,17 @@ impl Flow for BlockFlow { self.base.flags.set_inorder(false); } - for box in self.box.iter() { - let style = box.style(); + for box_ in self.box_.iter() { + let style = box_.style(); // The text alignment of a block flow is the text alignment of its box's style. self.base.flags.set_text_align(style.Text.text_align); // Can compute padding here since we know containing block width. - box.compute_padding(style, remaining_width); + box_.compute_padding(style, remaining_width); // Margins are 0 right now so base.noncontent_width() is just borders + padding. - let available_width = remaining_width - box.noncontent_width(); + let available_width = remaining_width - box_.noncontent_width(); // Top and bottom margins for blocks are 0 if auto. let margin_top = MaybeAuto::from_style(style.Margin.margin_top, @@ -631,25 +631,25 @@ impl Flow for BlockFlow { remaining_width).specified_or_zero(); let (width, margin_left, margin_right) = if self.is_float() { - self.compute_float_margins(box, remaining_width) + self.compute_float_margins(box_, remaining_width) } else { - self.compute_block_margins(box, remaining_width, available_width) + self.compute_block_margins(box_, remaining_width, available_width) }; - box.margin.set(SideOffsets2D::new(margin_top, + box_.margin.set(SideOffsets2D::new(margin_top, margin_right, margin_bottom, margin_left)); - x_offset = box.offset(); + x_offset = box_.offset(); remaining_width = width; // The associated box is the border box of this flow. - let position_ref = box.position.mutate(); - position_ref.ptr.origin.x = box.margin.get().left; - let padding_and_borders = box.padding.get().left + box.padding.get().right + - box.border.get().left + box.border.get().right; - position_ref.ptr.size.width = remaining_width + padding_and_borders; + let mut position_ref = box_.position.borrow_mut(); + position_ref.get().origin.x = box_.margin.get().left; + let padding_and_borders = box_.padding.get().left + box_.padding.get().right + + box_.border.get().left + box_.border.get().right; + position_ref.get().size.width = remaining_width + padding_and_borders; } if self.is_float() { @@ -722,24 +722,24 @@ impl Flow for BlockFlow { return; } - for box in self.box.iter() { + for box_ in self.box_.iter() { // The top margin collapses with its first in-flow block-level child's // top margin if the parent has no top border, no top padding. if *first_in_flow && top_margin_collapsible { // If top-margin of parent is less than top-margin of its first child, // the parent box goes down until its top is aligned with the child. - if *margin_top < box.margin.get().top { + if *margin_top < box_.margin.get().top { // TODO: The position of child floats should be updated and this // would influence clearance as well. See #725 - let extra_margin = box.margin.get().top - *margin_top; + let extra_margin = box_.margin.get().top - *margin_top; *top_offset = *top_offset + extra_margin; - *margin_top = box.margin.get().top; + *margin_top = box_.margin.get().top; } } // The bottom margin of an in-flow block-level element collapses // with the top margin of its next in-flow block-level sibling. - *collapsing = geometry::min(box.margin.get().top, *collapsible); - *collapsible = box.margin.get().bottom; + *collapsing = geometry::min(box_.margin.get().top, *collapsible); + *collapsible = box_.margin.get().bottom; } *first_in_flow = false; @@ -757,7 +757,7 @@ impl Flow for BlockFlow { } else { ~"BlockFlow: " }; - txt.append(match self.box { + txt.append(match self.box_ { Some(ref rb) => rb.debug_str(), None => ~"", }) diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box_.rs index d1ed277a95b..57eed410b6a 100644 --- a/src/components/main/layout/box.rs +++ b/src/components/main/layout/box_.rs @@ -22,9 +22,8 @@ use servo_net::local_image_cache::LocalImageCache; use servo_util::geometry::Au; use servo_util::geometry; use servo_util::range::*; -use servo_util::slot::Slot; use std::cast; -use std::cell::Cell; +use std::cell::RefCell; use std::cmp::ApproxEq; use std::num::Zero; use style::{ComputedValues, TElement, TNode, cascade}; @@ -71,24 +70,24 @@ pub struct Box { style: Arc<ComputedValues>, /// The position of this box relative to its owning flow. - position: Slot<Rect<Au>>, + position: RefCell<Rect<Au>>, /// The border of the content box. /// /// FIXME(pcwalton): This need not be stored in the box. - border: Slot<SideOffsets2D<Au>>, + border: RefCell<SideOffsets2D<Au>>, /// The padding of the content box. - padding: Slot<SideOffsets2D<Au>>, + padding: RefCell<SideOffsets2D<Au>>, /// The margin of the content box. - margin: Slot<SideOffsets2D<Au>>, + margin: RefCell<SideOffsets2D<Au>>, /// Info specific to the kind of box. Keep this enum small. specific: SpecificBoxInfo, /// positioned box offsets - position_offsets: Slot<SideOffsets2D<Au>>, + position_offsets: RefCell<SideOffsets2D<Au>>, } /// Info specific to the kind of box. Keep this enum small. @@ -105,7 +104,7 @@ pub enum SpecificBoxInfo { #[deriving(Clone)] pub struct ImageBoxInfo { /// The image held within this box. - image: Slot<ImageHolder>, + image: RefCell<ImageHolder>, /// The width attribute supplied by the DOM, if any. dom_width: Option<Au>, /// The height attribute supplied by the DOM, if any. @@ -129,7 +128,7 @@ impl ImageBoxInfo { } ImageBoxInfo { - image: Slot::init(ImageHolder::new(image_url, local_image_cache)), + image: RefCell::new(ImageHolder::new(image_url, local_image_cache)), dom_width: convert_length(node, "width"), dom_height: convert_length(node, "height"), } @@ -139,7 +138,8 @@ impl ImageBoxInfo { fn image_width(&self) -> Au { // TODO(brson): Consult margins and borders? self.dom_width.unwrap_or_else(|| { - Au::from_px(self.image.mutate().ptr.get_size().unwrap_or(Size2D(0, 0)).width) + let mut image_ref = self.image.borrow_mut(); + Au::from_px(image_ref.get().get_size().unwrap_or(Size2D(0, 0)).width) }) } @@ -147,7 +147,8 @@ impl ImageBoxInfo { pub fn image_height(&self) -> Au { // TODO(brson): Consult margins and borders? self.dom_height.unwrap_or_else(|| { - Au::from_px(self.image.mutate().ptr.get_size().unwrap_or(Size2D(0, 0)).height) + let mut image_ref = self.image.borrow_mut(); + Au::from_px(image_ref.get().get_size().unwrap_or(Size2D(0, 0)).height) }) } } @@ -256,12 +257,12 @@ impl Box { Box { node: OpaqueNode::from_layout_node(&node), style: node_style, - position: Slot::init(Au::zero_rect()), - border: Slot::init(Zero::zero()), - padding: Slot::init(Zero::zero()), - margin: Slot::init(Zero::zero()), + position: RefCell::new(Au::zero_rect()), + border: RefCell::new(Zero::zero()), + padding: RefCell::new(Zero::zero()), + margin: RefCell::new(Zero::zero()), specific: specific, - position_offsets: Slot::init(Zero::zero()), + position_offsets: RefCell::new(Zero::zero()), } } @@ -279,12 +280,12 @@ impl Box { Box { node: self.node, style: self.style.clone(), - position: Slot::init(Rect(self.position.get().origin, size)), - border: Slot::init(self.border.get()), - padding: Slot::init(self.padding.get()), - margin: Slot::init(self.margin.get()), + position: RefCell::new(Rect(self.position.get().origin, size)), + border: RefCell::new(self.border.get()), + padding: RefCell::new(self.padding.get()), + margin: RefCell::new(self.margin.get()), specific: specific, - position_offsets: Slot::init(Zero::zero()) + position_offsets: RefCell::new(Zero::zero()) } } @@ -310,11 +311,6 @@ impl Box { self.border.get().left + self.border.get().right } - /// Sets the size of this box. - fn set_size(&self, new_size: Size2D<Au>) { - self.position.set(Rect(self.position.get().origin, new_size)) - } - pub fn calculate_line_height(&self, font_size: Au) -> Au { match self.line_height() { line_height::Normal => font_size.scale_by(1.14), @@ -408,11 +404,11 @@ impl Box { debug!("(font style) start"); // FIXME: Too much allocation here. - let font_families = do my_style.Font.font_family.map |family| { + let font_families = my_style.Font.font_family.map(|family| { match *family { font_family::FamilyName(ref name) => (*name).clone(), } - }; + }); debug!("(font style) font families: `{:?}`", font_families); let font_size = my_style.Font.font_size.to_f64().unwrap() / 60.0; @@ -465,7 +461,7 @@ impl Box { /// and so on. pub fn is_replaced(&self) -> bool { match self.specific { - ImageBox(*) => true, + ImageBox(..) => true, _ => false, } } @@ -473,7 +469,7 @@ impl Box { /// Returns true if this element can be split. This is true for text boxes. pub fn can_split(&self) -> bool { match self.specific { - ScannedTextBox(*) => true, + ScannedTextBox(..) => true, _ => false, } } @@ -496,7 +492,7 @@ impl Box { /// necessary. pub fn paint_background_if_applicable<E:ExtraDisplayListData>( &self, - list: &Cell<DisplayList<E>>, + list: &RefCell<DisplayList<E>>, absolute_bounds: &Rect<Au>) { // FIXME: This causes a lot of background colors to be displayed when they are clearly not // needed. We could use display list optimization to clean this up, but it still seems @@ -505,7 +501,7 @@ impl Box { let style = self.style(); let background_color = style.resolve_color(style.Background.background_color); if !background_color.alpha.approx_eq(&0.0) { - list.with_mut_ref(|list| { + list.with_mut(|list| { let solid_color_display_item = ~SolidColorDisplayItem { base: BaseDisplayItem { bounds: *absolute_bounds, @@ -523,7 +519,7 @@ impl Box { /// necessary. pub fn paint_borders_if_applicable<E:ExtraDisplayListData>( &self, - list: &Cell<DisplayList<E>>, + list: &RefCell<DisplayList<E>>, abs_bounds: &Rect<Au>) { // Fast path. let border = self.border.get(); @@ -542,7 +538,7 @@ impl Box { let left_style = style.Border.border_left_style; // Append the border to the display list. - do list.with_mut_ref |list| { + list.with_mut(|list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: *abs_bounds, @@ -560,7 +556,7 @@ impl Box { }; list.append_item(BorderDisplayItemClass(border_display_item)) - } + }); } /// Adds the display items for this box to the given display list. @@ -583,7 +579,7 @@ impl Box { dirty: &Rect<Au>, offset: Point2D<Au>, flow: &Flow, - list: &Cell<DisplayList<E>>) { + list: &RefCell<DisplayList<E>>) { let box_bounds = self.position.get(); let absolute_box_bounds = box_bounds.translate(&offset); debug!("Box::build_display_list at rel={}, abs={}: {:s}", @@ -607,7 +603,7 @@ impl Box { match self.specific { UnscannedTextBox(_) => fail!("Shouldn't see unscanned boxes here."), ScannedTextBox(ref text_box) => { - do list.with_mut_ref |list| { + list.with_mut(|list| { let item = ~ClipDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -617,7 +613,7 @@ impl Box { need_clip: false }; list.append_item(ClipDisplayItemClass(item)); - } + }); let color = self.style().Color.color.to_gfx_color(); @@ -629,7 +625,7 @@ impl Box { text_flags.set_override_line_through(flow_flags.override_line_through()); // Create the text box. - do list.with_mut_ref |list| { + list.with_mut(|list| { let text_display_item = ~TextDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -642,7 +638,7 @@ impl Box { }; list.append_item(TextDisplayItemClass(text_display_item)) - } + }); // Draw debug frames for text bounds. // @@ -652,7 +648,7 @@ impl Box { // Compute the text box bounds and draw a border surrounding them. let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); - do list.with_mut_ref |list| { + list.with_mut(|list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -664,7 +660,7 @@ impl Box { }; list.append_item(BorderDisplayItemClass(border_display_item)) - } + }); // Draw a rectangle representing the baselines. // @@ -674,7 +670,7 @@ impl Box { let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent), Size2D(absolute_box_bounds.size.width, Au(0))); - do list.with_mut_ref |list| { + list.with_mut(|list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: baseline, @@ -686,13 +682,11 @@ impl Box { }; list.append_item(BorderDisplayItemClass(border_display_item)) - } - - () + }); }); }, - GenericBox | IframeBox(_) => { - do list.with_mut_ref |list| { + GenericBox | IframeBox(..) => { + list.with_mut(|list| { let item = ~ClipDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -702,14 +696,14 @@ impl Box { need_clip: self.needs_clip() }; list.append_item(ClipDisplayItemClass(item)); - } + }); // FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We // should have a real `SERVO_DEBUG` system. debug!("{:?}", { let debug_border = SideOffsets2D::new_all_same(Au::from_px(1)); - do list.with_mut_ref |list| { + list.with_mut(|list| { let border_display_item = ~BorderDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -721,13 +715,11 @@ impl Box { }; list.append_item(BorderDisplayItemClass(border_display_item)) - } - - () + }); }); }, ImageBox(ref image_box) => { - do list.with_mut_ref |list| { + list.with_mut(|list| { let item = ~ClipDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -737,14 +729,15 @@ impl Box { need_clip: false }; list.append_item(ClipDisplayItemClass(item)); - } + }); - match image_box.image.mutate().ptr.get_image() { + let mut image_ref = image_box.image.borrow_mut(); + match image_ref.get().get_image() { Some(image) => { debug!("(building display list) building image box"); // Place the image into the display list. - do list.with_mut_ref |list| { + list.with_mut(|list| { let image_display_item = ~ImageDisplayItem { base: BaseDisplayItem { bounds: absolute_box_bounds, @@ -752,8 +745,8 @@ impl Box { }, image: image.clone(), }; - list.append_item(ImageDisplayItemClass(image_display_item)) - } + list.append_item(ImageDisplayItemClass(image_display_item)); + }); } None => { // No image data at all? Do nothing. @@ -809,7 +802,7 @@ impl Box { (min_line_width, max_line_width) } - UnscannedTextBox(*) => fail!("Unscanned text boxes should have been scanned by now!"), + UnscannedTextBox(..) => fail!("Unscanned text boxes should have been scanned by now!"), }; (guessed_width + additional_minimum, guessed_width + additional_preferred) } @@ -822,11 +815,12 @@ impl Box { match self.specific { GenericBox | IframeBox(_) => Au(0), ImageBox(ref image_box_info) => { - let size = image_box_info.image.mutate().ptr.get_size(); + let mut image_ref = image_box_info.image.borrow_mut(); + let size = image_ref.get().get_size(); let height = Au::from_px(size.unwrap_or(Size2D(0, 0)).height); // Eww. Refactor this. - self.position.mutate().ptr.size.height = height; + self.position.borrow_mut().get().size.height = height; debug!("box_height: found image height: {}", height); height @@ -955,11 +949,11 @@ impl Box { match self.specific { GenericBox | IframeBox(_) => { // FIXME(pcwalton): This seems clownshoes; can we remove? - self.position.mutate().ptr.size.width = Au::from_px(45) + self.position.borrow_mut().get().size.width = Au::from_px(45) } ImageBox(ref image_box_info) => { let image_width = image_box_info.image_width(); - self.position.mutate().ptr.size.width = image_width + self.position.borrow_mut().get().size.width = image_width } ScannedTextBox(_) => { // Scanned text boxes will have already had their widths assigned by this point. diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index 80a8ffb8a1b..a0866cf934c 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -22,8 +22,8 @@ use css::node_style::StyledNode; use layout::block::BlockFlow; -use layout::box::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo}; -use layout::box::{UnscannedTextBox, UnscannedTextBoxInfo}; +use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo}; +use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo}; use layout::context::LayoutContext; use layout::float_context::FloatType; use layout::flow::{Flow, FlowData, MutableFlowUtils}; @@ -35,10 +35,11 @@ use layout::wrapper::{LayoutNode, PostorderNodeMutTraversal}; use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId}; use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId}; use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, TextNodeTypeId}; -use servo_util::slot::Slot; -use std::util; use style::computed_values::{display, float}; +use std::cell::RefCell; +use std::util; + /// The results of flow construction for a DOM node. pub enum ConstructionResult { /// This node contributes nothing at all (`display: none`). Alternately, this is what newly @@ -47,7 +48,7 @@ pub enum ConstructionResult { /// This node contributed a flow at the proper position in the tree. Nothing more needs to be /// done for this node. - FlowConstructionResult(~Flow:), + FlowConstructionResult(~Flow), /// This node contributed some object or objects that will be needed to construct a proper flow /// later up the tree, but these objects have not yet found their home. @@ -102,7 +103,7 @@ struct InlineBlockSplit { predecessor_boxes: ~[Box], /// The flow that caused this {ib} split. - flow: ~Flow:, + flow: ~Flow, } /// Methods on optional vectors. @@ -169,24 +170,24 @@ impl<T> OptVector<T> for Option<~[T]> { } /// An object that knows how to create flows. -pub struct FlowConstructor<'self> { +pub struct FlowConstructor<'a> { /// The layout context. /// /// FIXME(pcwalton): Why does this contain `@`??? That destroys parallelism!!! - layout_context: &'self mut LayoutContext, + layout_context: &'a mut LayoutContext, /// The next flow ID to assign. /// /// FIXME(pcwalton): This is going to have to be atomic; can't we do something better? - next_flow_id: Slot<int>, + next_flow_id: RefCell<int>, } -impl<'self> FlowConstructor<'self> { +impl<'fc> FlowConstructor<'fc> { /// Creates a new flow constructor. pub fn init<'a>(layout_context: &'a mut LayoutContext) -> FlowConstructor<'a> { FlowConstructor { layout_context: layout_context, - next_flow_id: Slot::init(0), + next_flow_id: RefCell::new(0), } } @@ -231,10 +232,10 @@ impl<'self> FlowConstructor<'self> { /// `#[inline(always)]` because this is performance critical and LLVM will not inline it /// otherwise. #[inline(always)] - fn flush_inline_boxes_to_flow(&mut self, boxes: ~[Box], flow: &mut ~Flow:, node: LayoutNode) { + fn flush_inline_boxes_to_flow(&mut self, boxes: ~[Box], flow: &mut ~Flow, node: LayoutNode) { if boxes.len() > 0 { let inline_base = FlowData::new(self.next_flow_id(), node); - let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow:; + let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow; TextRunScanner::new().scan_for_runs(self.layout_context, inline_flow); flow.add_new_child(inline_flow) } @@ -244,7 +245,7 @@ impl<'self> FlowConstructor<'self> { /// the given flow. fn flush_inline_boxes_to_flow_if_necessary(&mut self, opt_boxes: &mut Option<~[Box]>, - flow: &mut ~Flow:, + flow: &mut ~Flow, node: LayoutNode) { let opt_boxes = util::replace(opt_boxes, None); if opt_boxes.len() > 0 { @@ -256,7 +257,7 @@ impl<'self> FlowConstructor<'self> { /// other `BlockFlow`s or `InlineFlow`s will be populated underneath this node, depending on /// whether {ib} splits needed to happen. fn build_children_of_block_flow(&mut self, - flow: &mut ~Flow:, + flow: &mut ~Flow, node: LayoutNode) { // Gather up boxes for the inline flows we might need to create. let mut opt_boxes_for_inline_flow = None; @@ -342,10 +343,10 @@ impl<'self> FlowConstructor<'self> { /// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly /// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed /// to happen. - fn build_flow_for_block(&mut self, node: LayoutNode) -> ~Flow: { + fn build_flow_for_block(&mut self, node: LayoutNode) -> ~Flow { let base = FlowData::new(self.next_flow_id(), node); - let box = self.build_box_for_node(node); - let mut flow = ~BlockFlow::from_box(base, box) as ~Flow:; + let box_ = self.build_box_for_node(node); + let mut flow = ~BlockFlow::from_box(base, box_) as ~Flow; self.build_children_of_block_flow(&mut flow, node); flow } @@ -353,10 +354,10 @@ impl<'self> FlowConstructor<'self> { /// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with /// a `BlockFlow` underneath it. fn build_flow_for_floated_block(&mut self, node: LayoutNode, float_type: FloatType) - -> ~Flow: { + -> ~Flow { let base = FlowData::new(self.next_flow_id(), node); - let box = self.build_box_for_node(node); - let mut flow = ~BlockFlow::float_from_box(base, float_type, box) as ~Flow:; + let box_ = self.build_box_for_node(node); + let mut flow = ~BlockFlow::float_from_box(base, float_type, box_) as ~Flow; self.build_children_of_block_flow(&mut flow, node); flow } @@ -458,7 +459,7 @@ impl<'self> FlowConstructor<'self> { } } -impl<'self> PostorderNodeMutTraversal for FlowConstructor<'self> { +impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { // `#[inline(always)]` because this is always called from the traversal function and for some // reason LLVM's inlining heuristics go awry here. #[inline(always)] @@ -528,7 +529,7 @@ trait NodeUtils { fn swap_out_construction_result(self) -> ConstructionResult; } -impl<'self> NodeUtils for LayoutNode<'self> { +impl<'ln> NodeUtils for LayoutNode<'ln> { fn is_replaced_content(self) -> bool { match self.type_id() { TextNodeTypeId | @@ -543,17 +544,19 @@ impl<'self> NodeUtils for LayoutNode<'self> { #[inline(always)] fn set_flow_construction_result(self, result: ConstructionResult) { - match *self.mutate_layout_data().ptr { - Some(ref mut layout_data) => layout_data.flow_construction_result = result, + let mut layout_data_ref = self.mutate_layout_data(); + match *layout_data_ref.get() { + Some(ref mut layout_data) => layout_data.data.flow_construction_result = result, None => fail!("no layout data"), } } #[inline(always)] fn swap_out_construction_result(self) -> ConstructionResult { - match *self.mutate_layout_data().ptr { + let mut layout_data_ref = self.mutate_layout_data(); + match *layout_data_ref.get() { Some(ref mut layout_data) => { - util::replace(&mut layout_data.flow_construction_result, NoConstructionResult) + util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) } None => fail!("no layout data"), } @@ -568,14 +571,14 @@ fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) { // FIXME(pcwalton): This is slow because vector shift is broken. :( let mut found_nonwhitespace = false; let mut result = ~[]; - for box in boxes.move_iter() { - if !found_nonwhitespace && box.is_whitespace_only() { + for box_ in boxes.move_iter() { + if !found_nonwhitespace && box_.is_whitespace_only() { debug!("stripping ignorable whitespace from start"); continue } found_nonwhitespace = true; - result.push(box) + result.push(box_) } *opt_boxes = Some(result) diff --git a/src/components/main/layout/display_list_builder.rs b/src/components/main/layout/display_list_builder.rs index 7dd538d493d..dc20f784667 100644 --- a/src/components/main/layout/display_list_builder.rs +++ b/src/components/main/layout/display_list_builder.rs @@ -4,7 +4,7 @@ //! Constructs display lists from boxes. -use layout::box::Box; +use layout::box_::Box; use layout::context::LayoutContext; use layout::util::OpaqueNode; @@ -12,14 +12,14 @@ use gfx; use style; pub trait ExtraDisplayListData { - fn new(box: &Box) -> Self; + fn new(box_: &Box) -> Self; } pub type Nothing = (); impl ExtraDisplayListData for OpaqueNode { - fn new(box: &Box) -> OpaqueNode { - box.node + fn new(box_: &Box) -> OpaqueNode { + box_.node } } @@ -35,8 +35,8 @@ impl ExtraDisplayListData for Nothing { /// /// Right now, the builder isn't used for much, but it establishes the pattern we'll need once we /// support display-list-based hit testing and so forth. -pub struct DisplayListBuilder<'self> { - ctx: &'self LayoutContext, +pub struct DisplayListBuilder<'a> { + ctx: &'a LayoutContext, } // diff --git a/src/components/main/layout/extra.rs b/src/components/main/layout/extra.rs index c17bfc4e0e4..ba7cf8a2595 100644 --- a/src/components/main/layout/extra.rs +++ b/src/components/main/layout/extra.rs @@ -4,33 +4,39 @@ //! Code for managing the layout data in the DOM. -use layout::util::{LayoutData, LayoutDataAccess}; +use layout::util::{PrivateLayoutData, LayoutDataAccess, LayoutDataWrapper}; use layout::wrapper::LayoutNode; +use script::layout_interface::LayoutChan; /// Functionality useful for querying the layout-specific data on DOM nodes. pub trait LayoutAuxMethods { - fn initialize_layout_data(self); - fn initialize_style_for_subtree(self); + fn initialize_layout_data(self, chan: LayoutChan); + fn initialize_style_for_subtree(self, chan: LayoutChan); } -impl<'self> LayoutAuxMethods for LayoutNode<'self> { +impl<'ln> LayoutAuxMethods for LayoutNode<'ln> { /// Resets layout data and styles for the node. /// /// FIXME(pcwalton): Do this as part of box building instead of in a traversal. - fn initialize_layout_data(self) { - let layout_data_handle = self.mutate_layout_data(); - match *layout_data_handle.ptr { - None => *layout_data_handle.ptr = Some(~LayoutData::new()), + fn initialize_layout_data(self, chan: LayoutChan) { + let mut layout_data_ref = self.mutate_layout_data(); + match *layout_data_ref.get() { + None => { + *layout_data_ref.get() = Some(LayoutDataWrapper { + chan: Some(chan), + data: ~PrivateLayoutData::new(), + }); + } Some(_) => {} } } /// Resets layout data and styles for a Node tree. - /// + /// /// FIXME(pcwalton): Do this as part of box building instead of in a traversal. - fn initialize_style_for_subtree(self) { + fn initialize_style_for_subtree(self, chan: LayoutChan) { for n in self.traverse_preorder() { - n.initialize_layout_data(); + n.initialize_layout_data(chan.clone()); } } } diff --git a/src/components/main/layout/float_context.rs b/src/components/main/layout/float_context.rs index 7a92554401c..e61d3eb11c7 100644 --- a/src/components/main/layout/float_context.rs +++ b/src/components/main/layout/float_context.rs @@ -77,7 +77,7 @@ impl FloatContext { } #[inline(always)] - fn with_mut_base<R>(&mut self, callback: &fn(&mut FloatContextBase) -> R) -> R { + fn with_mut_base<R>(&mut self, callback: |&mut FloatContextBase| -> R) -> R { match *self { Invalid => fail!("Float context no longer available"), Valid(ref mut base) => callback(&mut *base) @@ -85,7 +85,7 @@ impl FloatContext { } #[inline(always)] - pub fn with_base<R>(&self, callback: &fn(&FloatContextBase) -> R) -> R { + pub fn with_base<R>(&self, callback: |&FloatContextBase| -> R) -> R { match *self { Invalid => fail!("Float context no longer available"), Valid(ref base) => callback(&*base) @@ -94,46 +94,46 @@ impl FloatContext { #[inline(always)] pub fn translate(&mut self, trans: Point2D<Au>) -> FloatContext { - do self.with_mut_base |base| { + self.with_mut_base(|base| { base.translate(trans); - } + }); replace(self, Invalid) } #[inline(always)] pub fn available_rect(&mut self, top: Au, height: Au, max_x: Au) -> Option<Rect<Au>> { - do self.with_base |base| { + self.with_base(|base| { base.available_rect(top, height, max_x) - } + }) } #[inline(always)] pub fn add_float(&mut self, info: &PlacementInfo) -> FloatContext{ - do self.with_mut_base |base| { + self.with_mut_base(|base| { base.add_float(info); - } + }); replace(self, Invalid) } #[inline(always)] pub fn place_between_floats(&self, info: &PlacementInfo) -> Rect<Au> { - do self.with_base |base| { + self.with_base(|base| { base.place_between_floats(info) - } + }) } #[inline(always)] pub fn last_float_pos(&mut self) -> Point2D<Au> { - do self.with_base |base| { + self.with_base(|base| { base.last_float_pos() - } + }) } #[inline(always)] pub fn clearance(&self, clear: ClearType) -> Au { - do self.with_base |base| { + self.with_base(|base| { base.clearance(clear) - } + }) } } @@ -288,24 +288,6 @@ impl FloatContextBase { self.floats_used += 1; } - /// Returns true if the given rect overlaps with any floats. - fn collides_with_float(&self, bounds: &Rect<Au>) -> bool { - for floats in self.float_data.iter() { - for float in floats.iter() { - match *float { - None => (), - Some(data) => { - if data.bounds.translate(&self.offset).intersects(bounds) { - return true; - } - } - }; - } - } - - return false; - } - /// Given the top 3 sides of the rectange, finds the largest height that /// will result in the rectange not colliding with any floats. Returns /// None if that height is infinite. diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs index d7d1f602f29..d6b377d92bc 100644 --- a/src/components/main/layout/flow.rs +++ b/src/components/main/layout/flow.rs @@ -27,7 +27,7 @@ use css::node_style::StyledNode; use layout::block::BlockFlow; -use layout::box::Box; +use layout::box_::Box; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::float_context::{FloatContext, Invalid}; @@ -42,7 +42,7 @@ use geom::rect::Rect; use gfx::display_list::{ClipDisplayItemClass, DisplayList}; use servo_util::geometry::Au; use std::cast; -use std::cell::Cell; +use std::cell::RefCell; use style::ComputedValues; use style::computed_values::text_align; @@ -127,7 +127,7 @@ pub fn base<'a>(this: &'a Flow) -> &'a FlowData { } /// Iterates over the children of this immutable flow. -pub fn imm_child_iter<'a>(flow: &'a Flow) -> DListIterator<'a,~Flow:> { +pub fn imm_child_iter<'a>(flow: &'a Flow) -> DListIterator<'a,~Flow> { base(flow).children.iter() } @@ -140,12 +140,12 @@ pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut FlowData { } /// Returns the last child of this flow. -pub fn last_child<'a>(flow: &'a mut Flow) -> Option<&'a mut ~Flow:> { +pub fn last_child<'a>(flow: &'a mut Flow) -> Option<&'a mut ~Flow> { mut_base(flow).children.back_mut() } /// Iterates over the children of this flow. -pub fn child_iter<'a>(flow: &'a mut Flow) -> MutDListIterator<'a,~Flow:> { +pub fn child_iter<'a>(flow: &'a mut Flow) -> MutDListIterator<'a,~Flow> { mut_base(flow).children.mut_iter() } @@ -183,13 +183,13 @@ pub trait MutableFlowUtils { // Mutators /// Adds a new flow as a child of this flow. - fn add_new_child(self, new_child: ~Flow:); + fn add_new_child(self, new_child: ~Flow); /// Invokes a closure with the first child of this flow. - fn with_first_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R; + fn with_first_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R; /// Invokes a closure with the last child of this flow. - fn with_last_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R; + fn with_last_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R; /// Removes the first child of this flow and destroys it. fn remove_first(self); @@ -205,7 +205,7 @@ pub trait MutableFlowUtils { self, builder: &DisplayListBuilder, dirty: &Rect<Au>, - list: &Cell<DisplayList<E>>) + list: &RefCell<DisplayList<E>>) -> bool; } @@ -385,7 +385,7 @@ pub struct FlowData { restyle_damage: RestyleDamage, /// The children of this flow. - children: DList<~Flow:>, + children: DList<~Flow>, /* TODO (Issue #87): debug only */ id: int, @@ -454,12 +454,12 @@ impl FlowData { } } - pub fn child_iter<'a>(&'a mut self) -> MutDListIterator<'a,~Flow:> { + pub fn child_iter<'a>(&'a mut self) -> MutDListIterator<'a,~Flow> { self.children.mut_iter() } } -impl<'self> ImmutableFlowUtils for &'self Flow { +impl<'a> ImmutableFlowUtils for &'a Flow { /// Returns true if this flow is a block or a float flow. fn is_block_like(self) -> bool { match self.class() { @@ -508,7 +508,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow { } } -impl<'self> MutableFlowUtils for &'self mut Flow { +impl<'a> MutableFlowUtils for &'a mut Flow { /// Traverses the tree in preorder. fn traverse_preorder<T:PreorderFlowTraversal>(self, traversal: &mut T) -> bool { if traversal.should_prune(self) { @@ -548,17 +548,17 @@ impl<'self> MutableFlowUtils for &'self mut Flow { } /// Adds a new flow as a child of this flow. - fn add_new_child(self, new_child: ~Flow:) { + fn add_new_child(self, new_child: ~Flow) { mut_base(self).children.push_back(new_child) } /// Invokes a closure with the first child of this flow. - fn with_first_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R { + fn with_first_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R { f(mut_base(self).children.front_mut()) } /// Invokes a closure with the last child of this flow. - fn with_last_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R { + fn with_last_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R { f(mut_base(self).children.back_mut()) } @@ -587,7 +587,7 @@ impl<'self> MutableFlowUtils for &'self mut Flow { self, builder: &DisplayListBuilder, dirty: &Rect<Au>, - list: &Cell<DisplayList<E>>) + list: &RefCell<DisplayList<E>>) -> bool { debug!("Flow: building display list for f{}", base(self).id); match self.class() { @@ -596,20 +596,21 @@ impl<'self> MutableFlowUtils for &'self mut Flow { _ => fail!("Tried to build_display_list_recurse of flow: {:?}", self), }; - if list.with_mut_ref(|list| list.list.len() == 0) { + if list.with_mut(|list| list.list.len() == 0) { return true; } - let child_list = ~Cell::new(DisplayList::new()); + let child_list = ~RefCell::new(DisplayList::new()); for kid in child_iter(self) { kid.build_display_list(builder,dirty,child_list); } - do list.with_mut_ref |list| { + let mut child_list = Some(child_list.unwrap()); + list.with_mut(|list| { let result = list.list.mut_rev_iter().position(|item| { match *item { ClipDisplayItemClass(ref mut item) => { - item.child_list.push_all_move(child_list.take().list); + item.child_list.push_all_move(child_list.take_unwrap().list); true }, _ => false, @@ -620,7 +621,7 @@ impl<'self> MutableFlowUtils for &'self mut Flow { fail!("fail to find parent item"); } - } + }); true } } diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs index 455f05a9249..42af73fab6c 100644 --- a/src/components/main/layout/inline.rs +++ b/src/components/main/layout/inline.rs @@ -3,14 +3,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use css::node_style::StyledNode; -use layout::box::{Box, CannotSplit, GenericBox, IframeBox, ImageBox, ScannedTextBox, SplitDidFit}; -use layout::box::{SplitDidNotFit, UnscannedTextBox}; +use layout::box_::{Box, CannotSplit, GenericBox, IframeBox, ImageBox, ScannedTextBox, SplitDidFit}; +use layout::box_::{SplitDidNotFit, UnscannedTextBox}; use layout::context::LayoutContext; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::flow::{FlowClass, Flow, FlowData, InlineFlowClass}; use layout::flow; use layout::float_context::FloatContext; -use layout::util::{ElementMapping}; +use layout::util::ElementMapping; use layout::float_context::{PlacementInfo, FloatLeft}; use extra::container::Deque; @@ -19,7 +19,7 @@ use geom::{Point2D, Rect, Size2D}; use gfx::display_list::DisplayList; use servo_util::geometry::Au; use servo_util::range::Range; -use std::cell::Cell; +use std::cell::RefCell; use std::u16; use std::util; use style::computed_values::{text_align, vertical_align}; @@ -80,18 +80,6 @@ impl LineboxScanner { } } - fn reinitialize(&mut self, float_ctx: FloatContext) { - self.floats = float_ctx; - self.new_boxes.truncate(0); - self.work_list.clear(); - self.pending_line.range = Range::empty(); - self.pending_line.bounds = Rect(Point2D(Au::new(0), Au::new(0)), - Size2D(Au::new(0), Au::new(0))); - self.pending_line.green_zone = Size2D(Au::new(0), Au::new(0)); - self.lines.truncate(0); - self.cur_y = Au::new(0); - } - pub fn floats_out(&mut self) -> FloatContext { self.floats.clone() } @@ -119,13 +107,13 @@ impl LineboxScanner { if flow.boxes.is_empty() { break; } - let box = flow.boxes.remove(0); // FIXME: use a linkedlist - debug!("LineboxScanner: Working with box from box list: b{}", box.debug_id()); - box + let box_ = flow.boxes.remove(0); // FIXME: use a linkedlist + debug!("LineboxScanner: Working with box from box list: b{}", box_.debug_id()); + box_ } else { - let box = self.work_list.pop_front().unwrap(); - debug!("LineboxScanner: Working with box from work list: b{}", box.debug_id()); - box + let box_ = self.work_list.pop_front().unwrap(); + debug!("LineboxScanner: Working with box from work list: b{}", box_.debug_id()); + box_ }; let box_was_appended = self.try_append_to_line(cur_box, flow); @@ -413,8 +401,8 @@ impl LineboxScanner { } // An unconditional push - fn push_box_to_line(&mut self, box: Box) { - debug!("LineboxScanner: Pushing box {} to line {:u}", box.debug_id(), self.lines.len()); + fn push_box_to_line(&mut self, box_: Box) { + debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len()); if self.pending_line.range.length() == 0 { assert!(self.new_boxes.len() <= (u16::max_value as uint)); @@ -422,10 +410,10 @@ impl LineboxScanner { } self.pending_line.range.extend_by(1); self.pending_line.bounds.size.width = self.pending_line.bounds.size.width + - box.position.get().size.width; + box_.position.get().size.width; self.pending_line.bounds.size.height = Au::max(self.pending_line.bounds.size.height, - box.position.get().size.height); - self.new_boxes.push(box); + box_.position.get().size.height); + self.new_boxes.push(box_); } } @@ -467,8 +455,8 @@ impl InlineFlow { } pub fn teardown(&mut self) { - for box in self.boxes.iter() { - box.teardown(); + for box_ in self.boxes.iter() { + box_.teardown(); } self.boxes = ~[]; } @@ -477,7 +465,7 @@ impl InlineFlow { &self, builder: &DisplayListBuilder, dirty: &Rect<Au>, - list: &Cell<DisplayList<E>>) + list: &RefCell<DisplayList<E>>) -> bool { let abs_rect = Rect(self.base.abs_position, self.base.position.size); if !abs_rect.intersects(dirty) { @@ -490,8 +478,8 @@ impl InlineFlow { self.base.id, self.boxes.len()); - for box in self.boxes.iter() { - box.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list) + for box_ in self.boxes.iter() { + box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list) } // TODO(#225): Should `inline-block` elements have flows as children of the inline flow or @@ -590,9 +578,9 @@ impl InlineFlow { }; for i in line.range.eachi() { - let box = &boxes[i]; - let size = box.position.get().size; - box.position.set(Rect(Point2D(offset_x, box.position.get().origin.y), size)); + let box_ = &boxes[i]; + let size = box_.position.get().size; + box_.position.set(Rect(Point2D(offset_x, box_.position.get().origin.y), size)); offset_x = offset_x + size.width; } } @@ -623,10 +611,10 @@ impl Flow for InlineFlow { let mut min_width = Au::new(0); let mut pref_width = Au::new(0); - for box in self.boxes.iter() { - debug!("Flow[{:d}]: measuring {:s}", self.base.id, box.debug_str()); + for box_ in self.boxes.iter() { + debug!("Flow[{:d}]: measuring {:s}", self.base.id, box_.debug_str()); let (this_minimum_width, this_preferred_width) = - box.minimum_and_preferred_widths(); + box_.minimum_and_preferred_widths(); min_width = Au::max(min_width, this_minimum_width); pref_width = Au::max(pref_width, this_preferred_width); } @@ -647,8 +635,8 @@ impl Flow for InlineFlow { { let this = &mut *self; - for box in this.boxes.iter() { - box.assign_width(); + for box_ in this.boxes.iter() { + box_.assign_width(); } } @@ -736,9 +724,9 @@ impl Flow for InlineFlow { let noncontent_height = top + bottom; height = height + noncontent_height; - let position_ref = cur_box.position.mutate(); - position_ref.ptr.size.height = height; - position_ref.ptr.translate(&Point2D(Au::new(0), -height)); + let mut position_ref = cur_box.position.borrow_mut(); + position_ref.get().size.height = height; + position_ref.get().translate(&Point2D(Au::new(0), -height)); let ascent = height + bottom; (height, Au::new(0), ascent) @@ -818,7 +806,7 @@ impl Flow for InlineFlow { bottommost = bottom_from_base; } - cur_box.position.mutate().ptr.origin.y = line.bounds.origin.y + offset; + cur_box.position.borrow_mut().get().origin.y = line.bounds.origin.y + offset; } // Calculate the distance from baseline to the top of the biggest box with 'bottom' @@ -847,7 +835,7 @@ impl Flow for InlineFlow { _ => baseline_offset, }; - cur_box.position.mutate().ptr.origin.y = cur_box.position.get().origin.y + + cur_box.position.borrow_mut().get().origin.y = cur_box.position.get().origin.y + adjust_offset; } diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index 2224401188a..740576617fd 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -16,7 +16,7 @@ use layout::flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTrave use layout::flow::{PostorderFlowTraversal}; use layout::flow; use layout::incremental::{RestyleDamage}; -use layout::util::{LayoutData, LayoutDataAccess, OpaqueNode}; +use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper}; use layout::wrapper::LayoutNode; use extra::arc::{Arc, RWArc, MutexArc}; @@ -34,7 +34,7 @@ use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId}; use script::layout_interface::{AddStylesheetMsg, ContentBoxQuery}; use script::layout_interface::{ContentBoxesQuery, ContentBoxesResponse, ExitNowMsg, LayoutQuery}; use script::layout_interface::{HitTestQuery, ContentBoxResponse, HitTestResponse}; -use script::layout_interface::{ContentChangedDocumentDamage, Msg, PrepareToExitMsg}; +use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, PrepareToExitMsg}; use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, ReflowDocumentDamage}; use script::layout_interface::{ReflowForDisplay, ReflowMsg}; use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg}; @@ -46,20 +46,22 @@ use servo_util::time::{ProfilerChan, profile}; use servo_util::time; use std::cast::transmute; use std::cast; -use std::cell::Cell; +use std::cell::RefCell; use std::comm::Port; -use std::task; use std::util; use style::{AuthorOrigin, Stylesheet, Stylist}; /// Information needed by the layout task. -struct LayoutTask { +pub struct LayoutTask { /// The ID of the pipeline that we belong to. id: PipelineId, /// The port on which we receive messages. port: Port<Msg>, + //// The channel to send messages to ourself. + chan: LayoutChan, + /// The channel on which messages can be sent to the constellation. constellation_chan: ConstellationChan, @@ -132,9 +134,9 @@ impl PreorderFlowTraversal for PropagateDamageTraversal { /// The bubble-widths traversal, the first part of layout computation. This computes preferred /// and intrinsic widths and bubbles them up the tree. -struct BubbleWidthsTraversal<'self>(&'self mut LayoutContext); +struct BubbleWidthsTraversal<'a>(&'a mut LayoutContext); -impl<'self> PostorderFlowTraversal for BubbleWidthsTraversal<'self> { +impl<'a> PostorderFlowTraversal for BubbleWidthsTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.bubble_widths(**self); @@ -151,9 +153,9 @@ impl<'self> PostorderFlowTraversal for BubbleWidthsTraversal<'self> { } /// The assign-widths traversal. In Gecko this corresponds to `Reflow`. -struct AssignWidthsTraversal<'self>(&'self mut LayoutContext); +struct AssignWidthsTraversal<'a>(&'a mut LayoutContext); -impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> { +impl<'a> PreorderFlowTraversal for AssignWidthsTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.assign_widths(**self); @@ -164,9 +166,9 @@ impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> { /// The assign-heights-and-store-overflow traversal, the last (and most expensive) part of layout /// computation. Determines the final heights for all layout objects, computes positions, and /// computes overflow regions. In Gecko this corresponds to `FinishAndStoreOverflow`. -struct AssignHeightsAndStoreOverflowTraversal<'self>(&'self mut LayoutContext); +struct AssignHeightsAndStoreOverflowTraversal<'a>(&'a mut LayoutContext); -impl<'self> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'self> { +impl<'a> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> { #[inline] fn process(&mut self, flow: &mut Flow) -> bool { flow.assign_height(**self); @@ -186,10 +188,10 @@ struct LayoutImageResponder { } impl ImageResponder for LayoutImageResponder { - fn respond(&self) -> ~fn(ImageResponseMsg) { + fn respond(&self) -> proc(ImageResponseMsg) { let id = self.id.clone(); let script_chan = self.script_chan.clone(); - let f: ~fn(ImageResponseMsg) = |_| { + let f: proc(ImageResponseMsg) = proc(_) { script_chan.send(SendEventMsg(id.clone(), ReflowEvent)) }; f @@ -200,6 +202,7 @@ impl LayoutTask { /// Spawns a new layout task. pub fn create(id: PipelineId, port: Port<Msg>, + chan: LayoutChan, constellation_chan: ConstellationChan, script_chan: ScriptChan, render_chan: RenderChan<OpaqueNode>, @@ -207,11 +210,11 @@ impl LayoutTask { opts: Opts, profiler_chan: ProfilerChan, shutdown_chan: Chan<()>) { - spawn_with!(task::task(), [port, constellation_chan, script_chan, - render_chan, img_cache_task, profiler_chan, shutdown_chan], { - { // Ensures LayoutTask gets destroyed before we send the shutdown message + spawn(proc() { + { // Ensures layout task is destroyed before we send shutdown message let mut layout = LayoutTask::new(id, port, + chan, constellation_chan, script_chan, render_chan, @@ -220,7 +223,6 @@ impl LayoutTask { profiler_chan); layout.start(); } - shutdown_chan.send(()); }); } @@ -228,6 +230,7 @@ impl LayoutTask { /// Creates a new `LayoutTask` structure. fn new(id: PipelineId, port: Port<Msg>, + chan: LayoutChan, constellation_chan: ConstellationChan, script_chan: ScriptChan, render_chan: RenderChan<OpaqueNode>, @@ -239,6 +242,7 @@ impl LayoutTask { LayoutTask { id: id, port: port, + chan: chan, constellation_chan: constellation_chan, script_chan: script_chan, render_chan: render_chan, @@ -281,17 +285,15 @@ impl LayoutTask { match self.port.recv() { AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet), ReflowMsg(data) => { - let data = Cell::new(data); - - do profile(time::LayoutPerformCategory, self.profiler_chan.clone()) { - self.handle_reflow(data.take()); - } + profile(time::LayoutPerformCategory, self.profiler_chan.clone(), || { + self.handle_reflow(data); + }); } QueryMsg(query) => { - let query = Cell::new(query); - do profile(time::LayoutQueryCategory, self.profiler_chan.clone()) { - self.handle_query(query.take()); - } + let mut query = Some(query); + profile(time::LayoutQueryCategory, self.profiler_chan.clone(), || { + self.handle_query(query.take_unwrap()); + }); } ReapLayoutDataMsg(dead_layout_data) => { unsafe { @@ -340,16 +342,16 @@ impl LayoutTask { /// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely) /// crash. fn exit_now(&mut self) { - let (response_port, response_chan) = stream(); + let (response_port, response_chan) = Chan::new(); self.render_chan.send(render_task::ExitMsg(response_chan)); response_port.recv() } fn handle_add_stylesheet(&mut self, sheet: Stylesheet) { - let sheet = Cell::new(sheet); - do self.stylist.write |stylist| { - stylist.add_stylesheet(sheet.take(), AuthorOrigin); - } + let mut sheet = Some(sheet); + self.stylist.write(|stylist| { + stylist.add_stylesheet(sheet.take_unwrap(), AuthorOrigin); + }); } /// Builds the flow tree. @@ -359,12 +361,13 @@ impl LayoutTask { /// is intertwined with selector matching, making it difficult to compare directly. It is /// marked `#[inline(never)]` to aid benchmarking in sampling profilers. #[inline(never)] - fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode) -> ~Flow: { + fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode) -> ~Flow { node.traverse_postorder_mut(&mut FlowConstructor::init(layout_context)); - let result = match *node.mutate_layout_data().ptr { + let mut layout_data_ref = node.mutate_layout_data(); + let result = match *layout_data_ref.get() { Some(ref mut layout_data) => { - util::replace(&mut layout_data.flow_construction_result, NoConstructionResult) + util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult) } None => fail!("no layout data for root node"), }; @@ -436,18 +439,18 @@ impl LayoutTask { // Initialize layout data for each node. // // FIXME: This is inefficient. We don't need an entire traversal to do this! - do profile(time::LayoutAuxInitCategory, self.profiler_chan.clone()) { - node.initialize_style_for_subtree(); - } + profile(time::LayoutAuxInitCategory, self.profiler_chan.clone(), || { + node.initialize_style_for_subtree(self.chan.clone()); + }); // Perform CSS selector matching if necessary. match data.damage.level { ReflowDocumentDamage => {} _ => { - do profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone()) { + profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone(), || { node.match_subtree(self.stylist.clone()); node.cascade_subtree(None); - } + }); } } @@ -464,25 +467,25 @@ impl LayoutTask { // Perform the primary layout passes over the flow tree to compute the locations of all // the boxes. - do profile(time::LayoutMainCategory, self.profiler_chan.clone()) { + profile(time::LayoutMainCategory, self.profiler_chan.clone(), || { self.solve_constraints(layout_root, &mut layout_ctx) - } + }); debug!("layout: constraint solving done:"); debug!("{:?}", layout_root.dump()); // Build the display list if necessary, and send it to the renderer. if data.goal == ReflowForDisplay { - do profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone()) { + profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone(), || { let root_size = flow::base(layout_root).position.size; - let display_list = ~Cell::new(DisplayList::<OpaqueNode>::new()); + let display_list = ~RefCell::new(DisplayList::<OpaqueNode>::new()); let dirty = flow::base(layout_root).position.clone(); let display_list_builder = DisplayListBuilder { ctx: &layout_ctx, }; layout_root.build_display_list(&display_list_builder, &dirty, display_list); - let display_list = Arc::new(display_list.take()); + let display_list = Arc::new(display_list.unwrap()); let mut color = color::rgba(255.0, 255.0, 255.0, 255.0); @@ -516,7 +519,7 @@ impl LayoutTask { self.display_list = Some(display_list.clone()); self.render_chan.send(RenderMsg(render_layer)); - } // time(layout: display list building) + }); } // Tell script that we're done. @@ -663,8 +666,9 @@ impl LayoutTask { /// Handles a message to destroy layout data. Layout data must be destroyed on *this* task /// because it contains local managed pointers. unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) { - let ptr: &mut Option<~LayoutData> = cast::transmute(layout_data.borrow_unchecked()); - *ptr = None + let mut layout_data_ref = layout_data.borrow_mut(); + let _: Option<LayoutDataWrapper> = cast::transmute( + util::replace(layout_data_ref.get(), None)); } } diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs index bc3059695d6..72695c691b2 100644 --- a/src/components/main/layout/text.rs +++ b/src/components/main/layout/text.rs @@ -4,7 +4,7 @@ //! Text layout. -use layout::box::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox}; +use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox}; use layout::context::LayoutContext; use layout::flow::Flow; @@ -15,7 +15,7 @@ use servo_util::range::Range; use std::vec; /// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es. -struct TextRunScanner { +pub struct TextRunScanner { clump: Range, } @@ -123,7 +123,7 @@ impl TextRunScanner { // font group fonts. This is probably achieved by creating the font group above // and then letting `FontGroup` decide which `Font` to stick into the text run. let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style); - let run = ~fontgroup.with_borrow(|fg| fg.create_textrun(transformed_text.clone(), decoration)); + let run = ~fontgroup.borrow().with(|fg| fg.create_textrun(transformed_text.clone(), decoration)); debug!("TextRunScanner: pushing single text box in range: {} ({})", self.clump, @@ -142,7 +142,7 @@ impl TextRunScanner { // First, transform/compress text of all the nodes. let mut last_whitespace_in_clump = new_whitespace; - let transformed_strs: ~[~str] = do vec::from_fn(self.clump.length()) |i| { + let transformed_strs: ~[~str] = vec::from_fn(self.clump.length(), |i| { // TODO(#113): We should be passing the compression context between calls to // `transform_text`, so that boxes starting and/or ending with whitespace can // be compressed correctly with respect to the text run. @@ -157,7 +157,7 @@ impl TextRunScanner { last_whitespace_in_clump); last_whitespace_in_clump = new_whitespace; new_str - }; + }); new_whitespace = last_whitespace_in_clump; // Next, concatenate all of the transformed strings together, saving the new @@ -186,8 +186,8 @@ impl TextRunScanner { // sequence. If no clump takes ownership, however, it will leak. let clump = self.clump; let run = if clump.length() != 0 && run_str.len() > 0 { - fontgroup.with_borrow( |fg| { - fg.fonts[0].with_mut_borrow( |font| { + fontgroup.borrow().with(|fg| { + fg.fonts[0].borrow().with_mut(|font| { Some(Arc::new(~TextRun::new(font, run_str.clone(), decoration))) }) }) @@ -216,14 +216,14 @@ impl TextRunScanner { } // End of match. debug!("--- In boxes: ---"); - for (i, box) in in_boxes.iter().enumerate() { - debug!("{:u} --> {:s}", i, box.debug_str()); + for (i, box_) in in_boxes.iter().enumerate() { + debug!("{:u} --> {:s}", i, box_.debug_str()); } debug!("------------------"); debug!("--- Out boxes: ---"); - for (i, box) in out_boxes.iter().enumerate() { - debug!("{:u} --> {:s}", i, box.debug_str()); + for (i, box_) in out_boxes.iter().enumerate() { + debug!("{:u} --> {:s}", i, box_.debug_str()); } debug!("------------------"); diff --git a/src/components/main/layout/util.rs b/src/components/main/layout/util.rs index a5dc5047968..65cf0b6b676 100644 --- a/src/components/main/layout/util.rs +++ b/src/components/main/layout/util.rs @@ -2,15 +2,16 @@ * 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::box::Box; +use layout::box_::Box; use layout::construct::{ConstructionResult, NoConstructionResult}; use layout::wrapper::LayoutNode; use extra::arc::Arc; use script::dom::node::AbstractNode; +use script::layout_interface::LayoutChan; use servo_util::range::Range; -use servo_util::slot::{MutSlotRef, SlotRef}; use std::cast; +use std::cell::{Ref, RefMut}; use std::iter::Enumerate; use std::libc::uintptr_t; use std::vec::VecIterator; @@ -31,7 +32,7 @@ impl NodeRange { } } -struct ElementMapping { +pub struct ElementMapping { priv entries: ~[NodeRange], } @@ -46,7 +47,7 @@ impl ElementMapping { self.entries.push(NodeRange::new(node, range)) } - pub fn each(&self, callback: &fn(nr: &NodeRange) -> bool) -> bool { + pub fn each(&self, callback: |nr: &NodeRange| -> bool) -> bool { for nr in self.entries.iter() { if !callback(nr) { break @@ -63,14 +64,14 @@ impl ElementMapping { let entries = &mut self.entries; debug!("--- Old boxes: ---"); - for (i, box) in old_boxes.iter().enumerate() { - debug!("{:u} --> {:s}", i, box.debug_str()); + for (i, box_) in old_boxes.iter().enumerate() { + debug!("{:u} --> {:s}", i, box_.debug_str()); } debug!("------------------"); debug!("--- New boxes: ---"); - for (i, box) in new_boxes.iter().enumerate() { - debug!("{:u} --> {:s}", i, box.debug_str()); + for (i, box_) in new_boxes.iter().enumerate() { + debug!("{:u} --> {:s}", i, box_.debug_str()); } debug!("------------------"); @@ -125,7 +126,7 @@ impl ElementMapping { } /// Data that layout associates with a node. -pub struct LayoutData { +pub struct PrivateLayoutData { /// The results of CSS matching for this node. before_applicable_declarations: ~[Arc<~[PropertyDeclaration]>], @@ -148,10 +149,10 @@ pub struct LayoutData { flow_construction_result: ConstructionResult, } -impl LayoutData { +impl PrivateLayoutData { /// Creates new layout data. - pub fn new() -> LayoutData { - LayoutData { + pub fn new() -> PrivateLayoutData { + PrivateLayoutData { applicable_declarations: ~[], before_applicable_declarations: ~[], after_applicable_declarations: ~[], @@ -164,35 +165,35 @@ impl LayoutData { } } +pub struct LayoutDataWrapper { + chan: Option<LayoutChan>, + data: ~PrivateLayoutData, +} + /// A trait that allows access to the layout data of a DOM node. pub trait LayoutDataAccess { /// Borrows the layout data without checks. /// /// FIXME(pcwalton): Make safe. - unsafe fn borrow_layout_data_unchecked<'a>(&'a self) -> &'a Option<~LayoutData>; + // unsafe fn borrow_layout_data_unchecked<'a>(&'a self) -> &'a Option<~LayoutData>; /// Borrows the layout data immutably. Fails on a conflicting borrow. - fn borrow_layout_data<'a>(&'a self) -> SlotRef<'a,Option<~LayoutData>>; + fn borrow_layout_data<'a>(&'a self) -> Ref<'a,Option<LayoutDataWrapper>>; /// Borrows the layout data mutably. Fails on a conflicting borrow. - fn mutate_layout_data<'a>(&'a self) -> MutSlotRef<'a,Option<~LayoutData>>; + fn mutate_layout_data<'a>(&'a self) -> RefMut<'a,Option<LayoutDataWrapper>>; } -impl<'self> LayoutDataAccess for LayoutNode<'self> { - #[inline(always)] - unsafe fn borrow_layout_data_unchecked<'a>(&'a self) -> &'a Option<~LayoutData> { - cast::transmute(self.get().layout_data.borrow_unchecked()) - } - +impl<'ln> LayoutDataAccess for LayoutNode<'ln> { #[inline(always)] - fn borrow_layout_data<'a>(&'a self) -> SlotRef<'a,Option<~LayoutData>> { + fn borrow_layout_data<'a>(&'a self) -> Ref<'a,Option<LayoutDataWrapper>> { unsafe { cast::transmute(self.get().layout_data.borrow()) } } #[inline(always)] - fn mutate_layout_data<'a>(&'a self) -> MutSlotRef<'a,Option<~LayoutData>> { + fn mutate_layout_data<'a>(&'a self) -> RefMut<'a,Option<LayoutDataWrapper>> { unsafe { - cast::transmute(self.get().layout_data.mutate()) + cast::transmute(self.get().layout_data.borrow_mut()) } } } diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs index 619c711329a..f41fdb67d26 100644 --- a/src/components/main/layout/wrapper.rs +++ b/src/components/main/layout/wrapper.rs @@ -29,17 +29,17 @@ use style::{PropertyDeclarationBlock, TElement, TNode}; /// A wrapper so that layout can access only the methods that it should have access to. Layout must /// only ever see these and must never see instances of `AbstractNode`. #[deriving(Clone, Eq)] -pub struct LayoutNode<'self> { +pub struct LayoutNode<'a> { /// The wrapped node. priv node: AbstractNode, /// Being chained to a value prevents `LayoutNode`s from escaping. - priv chain: &'self (), + priv chain: &'a (), } -impl<'self> LayoutNode<'self> { +impl<'ln> LayoutNode<'ln> { /// Creates a new layout node, scoped to the given closure. - pub unsafe fn with_layout_node<R>(node: AbstractNode, f: &fn<'a>(LayoutNode<'a>) -> R) -> R { + pub unsafe fn with_layout_node<R>(node: AbstractNode, f: <'a> |LayoutNode<'a>| -> R) -> R { let heavy_iron_ball = (); f(LayoutNode { node: node, @@ -48,7 +48,7 @@ impl<'self> LayoutNode<'self> { } /// Creates a new layout node with the same lifetime as this layout node. - unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> LayoutNode<'self> { + unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> LayoutNode<'ln> { LayoutNode { node: node, chain: self.chain, @@ -62,14 +62,14 @@ impl<'self> LayoutNode<'self> { } /// Returns the first child of this node. - pub fn first_child(&self) -> Option<LayoutNode<'self>> { + pub fn first_child(&self) -> Option<LayoutNode<'ln>> { unsafe { self.node.first_child().map(|node| self.new_with_this_lifetime(node)) } } /// Returns the first child of this node. - pub fn last_child(&self) -> Option<LayoutNode<'self>> { + pub fn last_child(&self) -> Option<LayoutNode<'ln>> { unsafe { self.node.last_child().map(|node| self.new_with_this_lifetime(node)) } @@ -78,14 +78,14 @@ impl<'self> LayoutNode<'self> { /// Iterates over this node and all its descendants, in preorder. /// /// FIXME(pcwalton): Terribly inefficient. We should use parallelism. - pub fn traverse_preorder(&self) -> LayoutTreeIterator<'self> { + pub fn traverse_preorder(&self) -> LayoutTreeIterator<'ln> { let mut nodes = ~[]; gather_layout_nodes(self, &mut nodes, false); LayoutTreeIterator::new(nodes) } /// Returns an iterator over this node's children. - pub fn children(&self) -> LayoutNodeChildrenIterator<'self> { + pub fn children(&self) -> LayoutNodeChildrenIterator<'ln> { LayoutNodeChildrenIterator { current_node: self.first_child(), } @@ -110,7 +110,7 @@ impl<'self> LayoutNode<'self> { /// Downcasts this node to an image element and calls the given closure. /// /// FIXME(pcwalton): RAII. - unsafe fn with_image_element<R>(self, f: &fn(&HTMLImageElement) -> R) -> R { + unsafe fn with_image_element<R>(self, f: |&HTMLImageElement| -> R) -> R { if !self.node.is_image_element() { fail!(~"node is not an image element"); } @@ -131,7 +131,7 @@ impl<'self> LayoutNode<'self> { /// Downcasts this node to an iframe element and calls the given closure. /// /// FIXME(pcwalton): RAII. - unsafe fn with_iframe_element<R>(self, f: &fn(&HTMLIFrameElement) -> R) -> R { + unsafe fn with_iframe_element<R>(self, f: |&HTMLIFrameElement| -> R) -> R { if !self.node.is_iframe_element() { fail!(~"node is not an iframe element"); } @@ -164,7 +164,7 @@ impl<'self> LayoutNode<'self> { /// Downcasts this node to a text node and calls the given closure. /// /// FIXME(pcwalton): RAII. - unsafe fn with_text<R>(self, f: &fn(&Text) -> R) -> R { + unsafe fn with_text<R>(self, f: |&Text| -> R) -> R { self.node.with_imm_text(f) } @@ -228,20 +228,20 @@ impl<'self> LayoutNode<'self> { } } -impl<'self> TNode<LayoutElement<'self>> for LayoutNode<'self> { - fn parent_node(&self) -> Option<LayoutNode<'self>> { +impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> { + fn parent_node(&self) -> Option<LayoutNode<'ln>> { unsafe { self.node.node().parent_node.map(|node| self.new_with_this_lifetime(node)) } } - fn prev_sibling(&self) -> Option<LayoutNode<'self>> { + fn prev_sibling(&self) -> Option<LayoutNode<'ln>> { unsafe { self.node.node().prev_sibling.map(|node| self.new_with_this_lifetime(node)) } } - fn next_sibling(&self) -> Option<LayoutNode<'self>> { + fn next_sibling(&self) -> Option<LayoutNode<'ln>> { unsafe { self.node.node().next_sibling.map(|node| self.new_with_this_lifetime(node)) } @@ -249,21 +249,21 @@ impl<'self> TNode<LayoutElement<'self>> for LayoutNode<'self> { fn is_element(&self) -> bool { match self.node.type_id() { - ElementNodeTypeId(*) => true, + ElementNodeTypeId(..) => true, _ => false } } fn is_document(&self) -> bool { match self.node.type_id() { - DocumentNodeTypeId(*) => true, + DocumentNodeTypeId(..) => true, _ => false } } /// If this is an element, accesses the element data. Fails if this is not an element node. #[inline] - fn with_element<R>(&self, f: &fn(&LayoutElement<'self>) -> R) -> R { + fn with_element<R>(&self, f: |&LayoutElement<'ln>| -> R) -> R { self.node.with_imm_element(|element| { // FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on // implementations. @@ -276,16 +276,16 @@ impl<'self> TNode<LayoutElement<'self>> for LayoutNode<'self> { } } -pub struct LayoutNodeChildrenIterator<'self> { - priv current_node: Option<LayoutNode<'self>>, +pub struct LayoutNodeChildrenIterator<'a> { + priv current_node: Option<LayoutNode<'a>>, } -impl<'self> Iterator<LayoutNode<'self>> for LayoutNodeChildrenIterator<'self> { - fn next(&mut self) -> Option<LayoutNode<'self>> { +impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> { + fn next(&mut self) -> Option<LayoutNode<'a>> { let node = self.current_node; - self.current_node = do self.current_node.and_then |node| { + self.current_node = self.current_node.and_then(|node| { node.next_sibling() - }; + }); node } } @@ -294,13 +294,13 @@ impl<'self> Iterator<LayoutNode<'self>> for LayoutNodeChildrenIterator<'self> { // Easy for preorder; harder for postorder. // // FIXME(pcwalton): Parallelism! Eventually this should just be nuked. -pub struct LayoutTreeIterator<'self> { - priv nodes: ~[LayoutNode<'self>], +pub struct LayoutTreeIterator<'a> { + priv nodes: ~[LayoutNode<'a>], priv index: uint, } -impl<'self> LayoutTreeIterator<'self> { - fn new(nodes: ~[LayoutNode<'self>]) -> LayoutTreeIterator<'self> { +impl<'a> LayoutTreeIterator<'a> { + fn new(nodes: ~[LayoutNode<'a>]) -> LayoutTreeIterator<'a> { LayoutTreeIterator { nodes: nodes, index: 0, @@ -308,8 +308,8 @@ impl<'self> LayoutTreeIterator<'self> { } } -impl<'self> Iterator<LayoutNode<'self>> for LayoutTreeIterator<'self> { - fn next(&mut self) -> Option<LayoutNode<'self>> { +impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> { + fn next(&mut self) -> Option<LayoutNode<'a>> { if self.index >= self.nodes.len() { None } else { @@ -360,17 +360,17 @@ pub trait PostorderNodeMutTraversal { } /// A wrapper around elements that ensures layout can only ever access safe properties. -pub struct LayoutElement<'self> { - priv element: &'self Element, +pub struct LayoutElement<'le> { + priv element: &'le Element, } -impl<'self> LayoutElement<'self> { - pub fn style_attribute(&self) -> &'self Option<PropertyDeclarationBlock> { +impl<'le> LayoutElement<'le> { + pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> { &self.element.style_attribute } } -impl<'self> TElement for LayoutElement<'self> { +impl<'le> TElement for LayoutElement<'le> { fn get_local_name<'a>(&'a self) -> &'a str { self.element.tag_name.as_slice() } |