diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs index 0aa4cf42d568..1857b1617c40 100644 --- a/src/components/main/layout/block.rs +++ b/src/components/main/layout/block.rs @@ -58,6 +58,8 @@ pub struct BlockFlow { /// Whether this block flow is the root flow. is_root: bool, + is_fixed: bool, + /// Additional floating flow members. float: Option<~FloatedBlockInfo> } @@ -68,15 +70,17 @@ impl BlockFlow { base: base, box_: None, is_root: false, + is_fixed: false, float: None } } - pub fn from_box(base: BaseFlow, box_: Box) -> BlockFlow { + pub fn from_box(base: BaseFlow, box_: Box, is_fixed: bool) -> BlockFlow { BlockFlow { base: base, box_: Some(box_), is_root: false, + is_fixed: is_fixed, float: None } } @@ -86,6 +90,7 @@ impl BlockFlow { base: base, box_: Some(box_), is_root: false, + is_fixed: false, float: Some(~FloatedBlockInfo::new(float_type)) } } @@ -95,6 +100,7 @@ impl BlockFlow { base: base, box_: None, is_root: true, + is_fixed: false, float: None } } @@ -104,6 +110,7 @@ impl BlockFlow { base: base, box_: None, is_root: false, + is_fixed: false, float: Some(~FloatedBlockInfo::new(float_type)) } } @@ -593,7 +600,7 @@ impl Flow for BlockFlow { }, self.base.id); - if self.is_root { + if self.is_root || self.is_fixed { debug!("Setting root position"); self.base.position.origin = Au::zero_point(); self.base.position.size.width = ctx.screen_size.size.width; diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs index 017dffecd0be..24ad026a212b 100644 --- a/src/components/main/layout/construct.rs +++ b/src/components/main/layout/construct.rs @@ -35,7 +35,7 @@ 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 style::computed_values::{display, float}; +use style::computed_values::{display, position, float}; use std::cell::RefCell; use std::util; @@ -344,10 +344,10 @@ impl<'fc> FlowConstructor<'fc> { /// 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, is_fixed: bool) -> ~Flow: { let base = BaseFlow::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 mut flow = ~BlockFlow::from_box(base, box_, is_fixed) as ~Flow:; self.build_children_of_block_flow(&mut flow, node); flow } @@ -363,6 +363,7 @@ impl<'fc> FlowConstructor<'fc> { flow } + /// Concatenates the boxes of kids, adding in our own borders/padding/margins if necessary. /// Returns the `InlineBoxesConstructionResult`, if any. There will be no /// `InlineBoxesConstructionResult` if this node consisted entirely of ignorable whitespace. @@ -504,47 +505,53 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> { #[inline(always)] fn process(&mut self, node: LayoutNode) -> bool { // Get the `display` property for this node, and determine whether this node is floated. - let (display, float) = match node.type_id() { + let (display, float, position) = match node.type_id() { ElementNodeTypeId(_) => { let style = node.style().get(); - (style.Box.display, style.Box.float) + (style.Box.display, style.Box.float, style.Box.position) } - TextNodeTypeId => (display::inline, float::none), + TextNodeTypeId => (display::inline, float::none, position::static_), CommentNodeTypeId | DoctypeNodeTypeId | DocumentFragmentNodeTypeId | - DocumentNodeTypeId(_) => (display::none, float::none), + DocumentNodeTypeId(_) => (display::none, float::none, position::static_), }; debug!("building flow for node: {:?} {:?}", display, float); // Switch on display and floatedness. - match (display, float) { + match (display, float, position) { // `display: none` contributes no flow construction result. Nuke the flow construction // results of children. - (display::none, _) => { + (display::none, _, _) => { for child in node.children() { child.set_flow_construction_result(NoConstructionResult) } } // Inline items contribute inline box construction results. - (display::inline, float::none) => { + (display::inline, float::none, _) => { let construction_result = self.build_boxes_for_inline(node); node.set_flow_construction_result(construction_result) + } // Block flows that are not floated contribute block flow construction results. // // TODO(pcwalton): Make this only trigger for blocks and handle the other `display` // properties separately. - (_, float::none) => { - let flow = self.build_flow_for_block(node); + + (_, _, position::fixed) => { + let flow = self.build_flow_for_block(node, true); + node.set_flow_construction_result(FlowConstructionResult(flow)) + } + (_, float::none, _) => { + let flow = self.build_flow_for_block(node, false); node.set_flow_construction_result(FlowConstructionResult(flow)) } // Floated flows contribute float flow construction results. - (_, float_value) => { + (_, float_value, _) => { let float_type = FloatType::from_property(float_value); let flow = self.build_flow_for_floated_block(node, float_type); node.set_flow_construction_result(FlowConstructionResult(flow)) diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs index 7b2dbfe1014c..7063b5501066 100644 --- a/src/components/main/layout/layout_task.rs +++ b/src/components/main/layout/layout_task.rs @@ -378,7 +378,7 @@ impl LayoutTask { }; flow.mark_as_root(); flow - } + } /// Performs layout constraint solving. /// @@ -399,7 +399,7 @@ impl LayoutTask { // For now, this is an inorder traversal // FIXME: prune this traversal as well let _ = layout_root.traverse_postorder(&mut - AssignHeightsAndStoreOverflowTraversal(layout_context)); + AssignHeightsAndStoreOverflowTraversal(layout_context)); } /// The high-level routine that performs layout tasks.