mirror of
https://github.com/servo/servo.git
synced 2025-08-07 14:35:33 +01:00
layout: Support multiple boxes per node; don't store fixed/absolute
descendant links separately
This commit is contained in:
parent
4fd950eae0
commit
98bf325e76
4 changed files with 84 additions and 102 deletions
|
@ -503,7 +503,7 @@ impl BlockFlow {
|
|||
-> BlockFlow {
|
||||
BlockFlow {
|
||||
base: BaseFlow::new((*node).clone()),
|
||||
box_: Some(Box::new(constructor, node)),
|
||||
box_: Some(Box::new(constructor, node, MainBoxKind)),
|
||||
is_root: false,
|
||||
static_y_offset: Au::new(0),
|
||||
float: None
|
||||
|
@ -528,7 +528,7 @@ impl BlockFlow {
|
|||
-> BlockFlow {
|
||||
BlockFlow {
|
||||
base: BaseFlow::new((*node).clone()),
|
||||
box_: Some(Box::new(constructor, node)),
|
||||
box_: Some(Box::new(constructor, node, MainBoxKind)),
|
||||
is_root: false,
|
||||
static_y_offset: Au::new(0),
|
||||
float: Some(~FloatedBlockInfo::new(float_kind))
|
||||
|
|
|
@ -22,14 +22,14 @@
|
|||
|
||||
use css::node_style::StyledNode;
|
||||
use layout::block::BlockFlow;
|
||||
use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo, TableBox};
|
||||
use layout::box_::{TableCellBox, TableColumnBox, TableColumnBoxInfo, TableRowBox, TableWrapperBox};
|
||||
use layout::box_::{InlineInfo, InlineParentInfo, SpecificBoxInfo, UnscannedTextBox};
|
||||
use layout::box_::{UnscannedTextBoxInfo};
|
||||
use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
|
||||
use layout::box_::{InlineInfo, InlineParentInfo, MainBoxKind, SpecificBoxInfo, SubBoxKind};
|
||||
use layout::box_::{TableBox, TableCellBox, TableColumnBox, TableColumnBoxInfo, TableRowBox};
|
||||
use layout::box_::{TableWrapperBox, UnscannedTextBox, UnscannedTextBoxInfo};
|
||||
use layout::context::LayoutContext;
|
||||
use layout::floats::FloatKind;
|
||||
use layout::flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
|
||||
use layout::flow::{Descendants, AbsDescendants, FixedDescendants};
|
||||
use layout::flow::{Descendants, AbsDescendants};
|
||||
use layout::flow_list::{Rawlink};
|
||||
use layout::inline::InlineFlow;
|
||||
use layout::table_wrapper::TableWrapperFlow;
|
||||
|
@ -40,31 +40,34 @@ use layout::table_rowgroup::TableRowGroupFlow;
|
|||
use layout::table_row::TableRowFlow;
|
||||
use layout::table_cell::TableCellFlow;
|
||||
use layout::text::TextRunScanner;
|
||||
use layout::util::{LayoutDataAccess, OpaqueNode};
|
||||
use layout::util::{LayoutDataAccess, OpaqueNodeMethods};
|
||||
use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
|
||||
use layout::wrapper::{Before, BeforeBlock, After, AfterBlock, Normal};
|
||||
|
||||
use extra::url::Url;
|
||||
use gfx::display_list::OpaqueNode;
|
||||
use gfx::font_context::FontContext;
|
||||
use script::dom::bindings::codegen::InheritTypes::TextCast;
|
||||
use script::dom::bindings::js::JS;
|
||||
use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId, HTMLObjectElementTypeId};
|
||||
use script::dom::element::{HTMLTableElementTypeId, HTMLTableSectionElementTypeId};
|
||||
use script::dom::element::{HTMLTableDataCellElementTypeId, HTMLTableHeaderCellElementTypeId};
|
||||
use script::dom::element::{HTMLTableColElementTypeId, HTMLTableRowElementTypeId};
|
||||
use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId};
|
||||
use script::dom::element::{HTMLObjectElementTypeId, HTMLPseudoElementTypeId};
|
||||
use script::dom::element::{HTMLTableColElementTypeId, HTMLTableDataCellElementTypeId};
|
||||
use script::dom::element::{HTMLTableElementTypeId, HTMLTableHeaderCellElementTypeId};
|
||||
use script::dom::element::{HTMLTableRowElementTypeId, HTMLTableSectionElementTypeId};
|
||||
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
|
||||
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
|
||||
use script::dom::node::{TextNodeTypeId};
|
||||
use script::dom::text::Text;
|
||||
use style::computed_values::{display, position, float, white_space};
|
||||
use style::ComputedValues;
|
||||
use servo_util::geometry::Au;
|
||||
use servo_util::namespace;
|
||||
use servo_util::url::parse_url;
|
||||
use servo_util::url::is_image_data;
|
||||
use servo_util::smallvec::SmallVec;
|
||||
use servo_util::str::is_whitespace;
|
||||
|
||||
use extra::url::Url;
|
||||
use sync::Arc;
|
||||
use servo_util::url::{is_image_data, parse_url};
|
||||
use std::mem;
|
||||
use std::num::Zero;
|
||||
use style::ComputedValues;
|
||||
use style::computed_values::{display, position, float, white_space};
|
||||
use sync::Arc;
|
||||
|
||||
/// The results of flow construction for a DOM node.
|
||||
pub enum ConstructionResult {
|
||||
|
@ -75,7 +78,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. It has bubbled up fixed
|
||||
/// and absolute descendant flows that have a CB above it.
|
||||
FlowConstructionResult(~Flow, AbsDescendants, FixedDescendants),
|
||||
FlowConstructionResult(~Flow, AbsDescendants),
|
||||
|
||||
/// 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.
|
||||
|
@ -86,7 +89,7 @@ impl ConstructionResult {
|
|||
fn destroy(&mut self) {
|
||||
match *self {
|
||||
NoConstructionResult => {}
|
||||
FlowConstructionResult(ref mut flow, _, _) => flow.destroy(),
|
||||
FlowConstructionResult(ref mut flow, _) => flow.destroy(),
|
||||
ConstructionItemConstructionResult(ref mut item) => item.destroy(),
|
||||
}
|
||||
}
|
||||
|
@ -132,9 +135,6 @@ struct InlineBoxesConstructionResult {
|
|||
|
||||
/// Any absolute descendants that we're bubbling up.
|
||||
abs_descendants: AbsDescendants,
|
||||
|
||||
/// Any fixed descendants that we're bubbling up.
|
||||
fixed_descendants: FixedDescendants,
|
||||
}
|
||||
|
||||
/// Represents an {ib} split that has not yet found the containing block that it belongs to. This
|
||||
|
@ -493,16 +493,13 @@ impl<'a> FlowConstructor<'a> {
|
|||
flow.set_abs_descendants(abs_descendants);
|
||||
abs_descendants = Descendants::new();
|
||||
|
||||
if is_fixed_positioned {
|
||||
// Send itself along with the other fixed descendants.
|
||||
fixed_descendants.push(Rawlink::some(flow));
|
||||
} else if is_absolutely_positioned {
|
||||
if is_fixed_positioned || is_absolutely_positioned {
|
||||
// This is now the only absolute flow in the subtree which hasn't yet
|
||||
// reached its CB.
|
||||
abs_descendants.push(Rawlink::some(flow));
|
||||
}
|
||||
}
|
||||
FlowConstructionResult(flow, abs_descendants, fixed_descendants)
|
||||
FlowConstructionResult(flow, abs_descendants)
|
||||
}
|
||||
|
||||
/// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly
|
||||
|
@ -521,7 +518,6 @@ impl<'a> FlowConstructor<'a> {
|
|||
self.build_flow_using_children(flow, node)
|
||||
}
|
||||
|
||||
|
||||
/// 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.
|
||||
|
@ -530,13 +526,12 @@ impl<'a> FlowConstructor<'a> {
|
|||
let mut opt_inline_block_splits = None;
|
||||
let mut opt_box_accumulator = None;
|
||||
let mut abs_descendants = Descendants::new();
|
||||
let mut fixed_descendants = Descendants::new();
|
||||
|
||||
// Concatenate all the boxes of our kids, creating {ib} splits as necessary.
|
||||
for kid in node.children() {
|
||||
match kid.swap_out_construction_result() {
|
||||
NoConstructionResult => {}
|
||||
FlowConstructionResult(flow, kid_abs_descendants, kid_fixed_descendants) => {
|
||||
FlowConstructionResult(flow, kid_abs_descendants) => {
|
||||
// {ib} split. Flush the accumulator to our new split and make a new
|
||||
// accumulator to hold any subsequent boxes we come across.
|
||||
let split = InlineBlockSplit {
|
||||
|
@ -545,14 +540,12 @@ impl<'a> FlowConstructor<'a> {
|
|||
};
|
||||
opt_inline_block_splits.push(split);
|
||||
abs_descendants.push_descendants(kid_abs_descendants);
|
||||
fixed_descendants.push_descendants(kid_fixed_descendants);
|
||||
}
|
||||
ConstructionItemConstructionResult(InlineBoxesConstructionItem(
|
||||
InlineBoxesConstructionResult {
|
||||
splits: opt_splits,
|
||||
boxes: boxes,
|
||||
abs_descendants: kid_abs_descendants,
|
||||
fixed_descendants: kid_fixed_descendants,
|
||||
})) => {
|
||||
|
||||
// Bubble up {ib} splits.
|
||||
|
@ -579,7 +572,6 @@ impl<'a> FlowConstructor<'a> {
|
|||
// Push residual boxes.
|
||||
opt_box_accumulator.push_all_move(boxes);
|
||||
abs_descendants.push_descendants(kid_abs_descendants);
|
||||
fixed_descendants.push_descendants(kid_fixed_descendants);
|
||||
}
|
||||
ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node,
|
||||
whitespace_style))
|
||||
|
@ -612,7 +604,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
for box_ in boxes.iter() {
|
||||
total.push(box_);
|
||||
}
|
||||
self.set_inline_info_for_inline_child(&total, node);
|
||||
self.set_inline_info_for_inline_child(total, node);
|
||||
|
||||
},
|
||||
None => {
|
||||
|
@ -622,7 +614,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
total.push(box_);
|
||||
}
|
||||
}
|
||||
self.set_inline_info_for_inline_child(&total, node);
|
||||
self.set_inline_info_for_inline_child(total, node);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -633,7 +625,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
for box_ in boxes.iter() {
|
||||
total.push(box_);
|
||||
}
|
||||
self.set_inline_info_for_inline_child(&total, node);
|
||||
self.set_inline_info_for_inline_child(total, node);
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
@ -648,7 +640,6 @@ impl<'a> FlowConstructor<'a> {
|
|||
splits: opt_inline_block_splits,
|
||||
boxes: opt_box_accumulator.to_vec(),
|
||||
abs_descendants: abs_descendants,
|
||||
fixed_descendants: fixed_descendants,
|
||||
});
|
||||
ConstructionItemConstructionResult(construction_item)
|
||||
} else {
|
||||
|
@ -656,10 +647,11 @@ impl<'a> FlowConstructor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): Why does this function create a box only to throw it away???
|
||||
fn set_inline_info_for_inline_child(&mut self,
|
||||
boxes: &~[&Box],
|
||||
boxes: &[&Box],
|
||||
parent_node: &ThreadSafeLayoutNode) {
|
||||
let parent_box = Box::new(self, parent_node);
|
||||
let parent_box = Box::new(self, parent_node, MainBoxKind);
|
||||
let font_style = parent_box.font_style();
|
||||
let font_group = self.font_context().get_resolved_font_for_style(&font_style);
|
||||
let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| {
|
||||
|
@ -671,33 +663,38 @@ impl<'a> FlowConstructor<'a> {
|
|||
let boxes_len = boxes.len();
|
||||
parent_box.compute_borders(parent_box.style());
|
||||
|
||||
// FIXME(pcwalton): I suspect that `Au(0)` is not correct for the containing block width.
|
||||
parent_box.compute_padding(parent_box.style(), Au(0));
|
||||
|
||||
for (i, box_) in boxes.iter().enumerate() {
|
||||
if box_.inline_info.with( |data| data.is_none() ) {
|
||||
box_.inline_info.set(Some(InlineInfo::new()));
|
||||
}
|
||||
|
||||
let mut border = parent_box.border.get();
|
||||
let mut padding = parent_box.padding.get();
|
||||
if i != 0 {
|
||||
border.left = Zero::zero();
|
||||
padding.left = Zero::zero()
|
||||
}
|
||||
if i != (boxes_len - 1) {
|
||||
border.right = Zero::zero();
|
||||
padding.right = Zero::zero()
|
||||
}
|
||||
|
||||
let mut info = box_.inline_info.borrow_mut();
|
||||
match info.get() {
|
||||
&Some(ref mut info) => {
|
||||
// TODO(ksh8281) compute margin,padding
|
||||
info.parent_info.push(
|
||||
InlineParentInfo {
|
||||
padding: Zero::zero(),
|
||||
border: border,
|
||||
margin: Zero::zero(),
|
||||
style: parent_box.style.clone(),
|
||||
font_ascent: font_ascent,
|
||||
font_descent: font_descent,
|
||||
node: OpaqueNode::from_thread_safe_layout_node(parent_node),
|
||||
});
|
||||
// TODO(ksh8281): Compute margins.
|
||||
info.parent_info.push(InlineParentInfo {
|
||||
padding: padding,
|
||||
border: border,
|
||||
margin: Zero::zero(),
|
||||
style: parent_box.style.clone(),
|
||||
font_ascent: font_ascent,
|
||||
font_descent: font_descent,
|
||||
node: OpaqueNodeMethods::from_thread_safe_layout_node(parent_node),
|
||||
})
|
||||
},
|
||||
&None => {}
|
||||
}
|
||||
|
@ -712,20 +709,22 @@ impl<'a> FlowConstructor<'a> {
|
|||
}
|
||||
|
||||
// If this node is ignorable whitespace, bail out now.
|
||||
//
|
||||
// FIXME(pcwalton): Don't do this if there's padding or borders.
|
||||
if node.is_ignorable_whitespace() {
|
||||
let opaque_node = OpaqueNode::from_thread_safe_layout_node(node);
|
||||
let opaque_node = OpaqueNodeMethods::from_thread_safe_layout_node(node);
|
||||
return ConstructionItemConstructionResult(WhitespaceConstructionItem(
|
||||
opaque_node,
|
||||
node.style().clone()))
|
||||
}
|
||||
|
||||
let mut opt_box_accumulator = None;
|
||||
opt_box_accumulator.push(Box::new(self, node, MainBoxKind));
|
||||
|
||||
let construction_item = InlineBoxesConstructionItem(InlineBoxesConstructionResult {
|
||||
splits: None,
|
||||
boxes: ~[
|
||||
Box::new(self, node)
|
||||
],
|
||||
boxes: opt_box_accumulator.to_vec(),
|
||||
abs_descendants: Descendants::new(),
|
||||
fixed_descendants: Descendants::new(),
|
||||
});
|
||||
ConstructionItemConstructionResult(construction_item)
|
||||
}
|
||||
|
@ -750,7 +749,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
for kid in node.children() {
|
||||
match kid.swap_out_construction_result() {
|
||||
NoConstructionResult | ConstructionItemConstructionResult(_) => {}
|
||||
FlowConstructionResult(kid_flow, _, _) => {
|
||||
FlowConstructionResult(kid_flow, _) => {
|
||||
// Only kid flows with table-caption are matched here.
|
||||
assert!(kid_flow.is_table_caption());
|
||||
table_wrapper_flow.add_new_child(kid_flow);
|
||||
|
@ -761,8 +760,10 @@ impl<'a> FlowConstructor<'a> {
|
|||
|
||||
/// Generates an anonymous table flow according to CSS 2.1 § 17.2.1, step 2.
|
||||
/// If necessary, generate recursively another anonymous table flow.
|
||||
fn generate_anonymous_missing_child(&mut self, child_flows: ~[~Flow],
|
||||
flow: &mut ~Flow, node: &ThreadSafeLayoutNode) {
|
||||
fn generate_anonymous_missing_child(&mut self,
|
||||
child_flows: ~[~Flow],
|
||||
flow: &mut ~Flow,
|
||||
node: &ThreadSafeLayoutNode) {
|
||||
let mut anonymous_flow = flow.generate_missing_child_flow(node);
|
||||
let mut consecutive_siblings = ~[];
|
||||
for kid_flow in child_flows.move_iter() {
|
||||
|
@ -805,10 +806,9 @@ impl<'a> FlowConstructor<'a> {
|
|||
// NOTE: The order of captions and table are not the same order as in the DOM tree.
|
||||
// All caption blocks are placed before the table flow
|
||||
match construction_result {
|
||||
FlowConstructionResult(table_flow, table_abs_descendants, table_fixed_descendants) => {
|
||||
FlowConstructionResult(table_flow, table_abs_descendants) => {
|
||||
wrapper_flow.add_new_child(table_flow);
|
||||
abs_descendants.push_descendants(table_abs_descendants);
|
||||
fixed_descendants.push_descendants(table_fixed_descendants);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -832,7 +832,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
abs_descendants.push(Rawlink::some(wrapper_flow));
|
||||
}
|
||||
}
|
||||
FlowConstructionResult(wrapper_flow, abs_descendants, fixed_descendants)
|
||||
FlowConstructionResult(wrapper_flow, abs_descendants)
|
||||
}
|
||||
|
||||
/// Builds a flow for a node with `display: table-caption`. This yields a `TableCaptionFlow`
|
||||
|
@ -904,7 +904,7 @@ impl<'a> FlowConstructor<'a> {
|
|||
let mut flow = ~TableColGroupFlow::from_node_and_boxes(node, box_, col_boxes) as ~Flow;
|
||||
flow.finish(self.layout_context);
|
||||
|
||||
FlowConstructionResult(flow, Descendants::new(), Descendants::new())
|
||||
FlowConstructionResult(flow, Descendants::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -922,6 +922,10 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
|||
fn process(&mut self, node: &ThreadSafeLayoutNode) -> bool {
|
||||
// Get the `display` property for this node, and determine whether this node is floated.
|
||||
let (display, float, positioning) = match node.type_id() {
|
||||
ElementNodeTypeId(HTMLPseudoElementTypeId) => {
|
||||
let style = node.style().get();
|
||||
(display::inline, style.Box.get().float, style.Box.get().position)
|
||||
}
|
||||
ElementNodeTypeId(_) => {
|
||||
let style = node.style().get();
|
||||
(style.Box.get().display, style.Box.get().float, style.Box.get().position)
|
||||
|
@ -1050,6 +1054,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
|||
DoctypeNodeTypeId |
|
||||
DocumentFragmentNodeTypeId |
|
||||
DocumentNodeTypeId |
|
||||
ElementNodeTypeId(HTMLPseudoElementTypeId) |
|
||||
ElementNodeTypeId(HTMLImageElementTypeId) => true,
|
||||
ElementNodeTypeId(HTMLObjectElementTypeId) => self.has_object_data(),
|
||||
ElementNodeTypeId(_) => false,
|
||||
|
|
|
@ -209,6 +209,11 @@ pub trait Flow {
|
|||
false
|
||||
}
|
||||
|
||||
/// Returns true if this is an absolute containing block.
|
||||
fn is_absolute_containing_block(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Return the dimensions of the CB generated _by_ this flow for absolute descendants.
|
||||
fn generated_cb_size(&self) -> Size2D<Au> {
|
||||
fail!("generated_cb_size not yet implemented")
|
||||
|
@ -372,11 +377,6 @@ pub trait MutableOwnedFlowUtils {
|
|||
/// Set this flow as the Containing Block for all the absolute descendants.
|
||||
fn set_abs_descendants(&mut self, abs_descendants: AbsDescendants);
|
||||
|
||||
/// Set fixed descendants for this flow.
|
||||
///
|
||||
/// Set yourself as the Containing Block for all the fixed descendants.
|
||||
fn set_fixed_descendants(&mut self, fixed_descendants: AbsDescendants);
|
||||
|
||||
/// Destroys the flow.
|
||||
fn destroy(&mut self);
|
||||
}
|
||||
|
@ -704,7 +704,6 @@ impl Descendants {
|
|||
}
|
||||
|
||||
pub type AbsDescendants = Descendants;
|
||||
pub type FixedDescendants = Descendants;
|
||||
|
||||
type DescendantIter<'a> = MutItems<'a, Rawlink>;
|
||||
|
||||
|
@ -749,15 +748,15 @@ pub struct BaseFlow {
|
|||
/// decide whether to do an in-order traversal for assign_height.
|
||||
num_floats: uint,
|
||||
|
||||
/// The collapsible margins for this flow, if any.
|
||||
collapsible_margins: CollapsibleMargins,
|
||||
|
||||
/// The position of this flow in page coordinates, computed during display list construction.
|
||||
abs_position: Point2D<Au>,
|
||||
|
||||
/// Details about descendants with position 'absolute' for which we are
|
||||
/// the CB. This is in tree order. This includes any direct children.
|
||||
/// Details about descendants with position 'absolute' or 'fixed' for which we are the
|
||||
/// containing block. This is in tree order. This includes any direct children.
|
||||
abs_descendants: AbsDescendants,
|
||||
/// Details about descendants with position 'fixed'.
|
||||
/// TODO: Optimize this, because this will be set only for the root.
|
||||
fixed_descendants: FixedDescendants,
|
||||
|
||||
/// Offset wrt the nearest positioned ancestor - aka the Containing Block
|
||||
/// for any absolutely positioned elements.
|
||||
|
@ -822,9 +821,10 @@ impl BaseFlow {
|
|||
|
||||
floats: Floats::new(),
|
||||
num_floats: 0,
|
||||
collapsible_margins: CollapsibleMargins::new(),
|
||||
clear: clear::none,
|
||||
abs_position: Point2D(Au::new(0), Au::new(0)),
|
||||
abs_descendants: Descendants::new(),
|
||||
fixed_descendants: Descendants::new(),
|
||||
absolute_static_x_offset: Au::new(0),
|
||||
fixed_static_x_offset: Au::new(0),
|
||||
absolute_cb: Rawlink::none(),
|
||||
|
@ -1081,6 +1081,7 @@ impl<'a> MutableFlowUtils for &'a mut Flow {
|
|||
overflow = overflow.union(&kid_overflow)
|
||||
}
|
||||
|
||||
// FIXME(pcwalton): This is wrong for `position: fixed`.
|
||||
for descendant_link in mut_base(self).abs_descendants.iter() {
|
||||
match descendant_link.resolve() {
|
||||
Some(flow) => {
|
||||
|
@ -1327,32 +1328,10 @@ impl MutableOwnedFlowUtils for ~Flow {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set fixed descendants for this flow.
|
||||
///
|
||||
/// Set yourself as the Containing Block for all the fixed descendants.
|
||||
///
|
||||
/// Assumption: This is called in a bottom-up traversal, so that nothing
|
||||
/// else is accessing the descendant flows.
|
||||
/// Assumption: This is the root flow.
|
||||
fn set_fixed_descendants(&mut self, fixed_descendants: FixedDescendants) {
|
||||
let self_link = Rawlink::some(*self);
|
||||
let block = self.as_block();
|
||||
block.base.fixed_descendants = fixed_descendants;
|
||||
|
||||
for descendant_link in block.base.fixed_descendants.iter() {
|
||||
match descendant_link.resolve() {
|
||||
Some(flow) => {
|
||||
let base = mut_base(flow);
|
||||
base.absolute_cb = self_link.clone();
|
||||
}
|
||||
None => fail!("empty Rawlink to a descendant")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Destroys the flow.
|
||||
fn destroy(&mut self) {
|
||||
let self_borrowed: &mut Flow = *self;
|
||||
self_borrowed.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -434,15 +434,13 @@ impl LayoutTask {
|
|||
None => fail!("no layout data for root node"),
|
||||
};
|
||||
let mut flow = match result {
|
||||
FlowConstructionResult(mut flow, abs_descendants, fixed_descendants) => {
|
||||
FlowConstructionResult(mut flow, abs_descendants) => {
|
||||
// Note: Assuming that the root has display 'static' (as per
|
||||
// CSS Section 9.3.1). Otherwise, if it were absolutely
|
||||
// positioned, it would return a reference to itself in
|
||||
// `abs_descendants` and would lead to a circular reference.
|
||||
// Set Root as CB for any remaining absolute descendants.
|
||||
flow.set_abs_descendants(abs_descendants);
|
||||
// Set Root as CB for all fixed descendants.
|
||||
flow.set_fixed_descendants(fixed_descendants);
|
||||
flow
|
||||
}
|
||||
_ => fail!("Flow construction didn't result in a flow at the root of the tree!"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue