mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
layout_2020: Use ArcRefCell to track hoisted fragments
This avoids the use of lookup tables for containing blocks when constructing the stacking context tree. This seems to catch some laid-out hoisted fragments that were otherwise dropped in the previous design. The changes cause one new test to pass and one to fail. Visual examination of the failing tests reveals that it's a progression (list markers are appearing when they were previously not rendered).
This commit is contained in:
parent
ebaa73ddcd
commit
19f4b708b3
8 changed files with 105 additions and 157 deletions
|
@ -304,12 +304,15 @@ impl InlineFormattingContext {
|
|||
},
|
||||
};
|
||||
let hoisted_box = box_.clone().to_hoisted(initial_start_corner, tree_rank);
|
||||
let hoisted_fragment_id = hoisted_box.fragment_id;
|
||||
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||
ifc.push_hoisted_box_to_positioning_context(hoisted_box);
|
||||
ifc.current_nesting_level.fragments_so_far.push(
|
||||
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment(
|
||||
hoisted_fragment_id,
|
||||
)),
|
||||
Fragment::AbsoluteOrFixedPositioned(
|
||||
AbsoluteOrFixedPositionedFragment {
|
||||
hoisted_fragment,
|
||||
position: box_.contents.style.clone_position(),
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
InlineLevelBox::OutOfFlowFloatBox(_box_) => {
|
||||
|
@ -492,7 +495,6 @@ impl<'box_tree> PartialInlineBoxFragment<'box_tree> {
|
|||
self.border.clone(),
|
||||
self.margin.clone(),
|
||||
CollapsedBlockMargins::zero(),
|
||||
None, // hoisted_fragment_id
|
||||
);
|
||||
let last_fragment = self.last_box_tree_fragment && !at_line_break;
|
||||
if last_fragment {
|
||||
|
@ -560,7 +562,6 @@ fn layout_atomic(
|
|||
border,
|
||||
margin,
|
||||
CollapsedBlockMargins::zero(),
|
||||
None, // hoisted_fragment_id
|
||||
)
|
||||
},
|
||||
Err(non_replaced) => {
|
||||
|
@ -636,7 +637,6 @@ fn layout_atomic(
|
|||
border,
|
||||
margin,
|
||||
CollapsedBlockMargins::zero(),
|
||||
None, // hoisted_fragment_id
|
||||
)
|
||||
},
|
||||
};
|
||||
|
|
|
@ -315,12 +315,13 @@ impl BlockLevelBox {
|
|||
))
|
||||
},
|
||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
|
||||
let hoisted_fragment = box_.clone().to_hoisted(Vec2::zero(), tree_rank);
|
||||
let hoisted_fragment_id = hoisted_fragment.fragment_id.clone();
|
||||
positioning_context.push(hoisted_fragment);
|
||||
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment(
|
||||
hoisted_fragment_id,
|
||||
))
|
||||
let hoisted_box = box_.clone().to_hoisted(Vec2::zero(), tree_rank);
|
||||
let hoisted_fragment = hoisted_box.fragment.clone();
|
||||
positioning_context.push(hoisted_box);
|
||||
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment {
|
||||
hoisted_fragment,
|
||||
position: box_.contents.style.clone_position(),
|
||||
})
|
||||
},
|
||||
BlockLevelBox::OutOfFlowFloatBox(_box_) => {
|
||||
// FIXME: call layout_maybe_position_relative_fragment here
|
||||
|
@ -501,7 +502,6 @@ fn layout_in_flow_non_replaced_block_level(
|
|||
border,
|
||||
margin,
|
||||
block_margins_collapsed_with_children,
|
||||
None, // hoisted_fragment_id
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -553,7 +553,6 @@ fn layout_in_flow_replaced_block_level<'a>(
|
|||
border,
|
||||
margin,
|
||||
block_margins_collapsed_with_children,
|
||||
None, // hoisted_fragment_id
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -147,48 +147,47 @@ impl BoxTreeRoot {
|
|||
let dummy_tree_rank = 0;
|
||||
let mut positioning_context =
|
||||
PositioningContext::new_for_containing_block_for_all_descendants();
|
||||
let mut independent_layout = self.0.layout(
|
||||
let independent_layout = self.0.layout(
|
||||
layout_context,
|
||||
&mut positioning_context,
|
||||
&(&initial_containing_block).into(),
|
||||
dummy_tree_rank,
|
||||
);
|
||||
|
||||
let mut children = independent_layout
|
||||
.fragments
|
||||
.into_iter()
|
||||
.map(|fragment| ArcRefCell::new(fragment))
|
||||
.collect();
|
||||
positioning_context.layout_initial_containing_block_children(
|
||||
layout_context,
|
||||
&initial_containing_block,
|
||||
&mut independent_layout.fragments,
|
||||
&mut children,
|
||||
);
|
||||
|
||||
let scrollable_overflow =
|
||||
independent_layout
|
||||
.fragments
|
||||
.iter()
|
||||
.fold(PhysicalRect::zero(), |acc, child| {
|
||||
let child_overflow = child.scrollable_overflow(&physical_containing_block);
|
||||
let scrollable_overflow = children.iter().fold(PhysicalRect::zero(), |acc, child| {
|
||||
let child_overflow = child
|
||||
.borrow()
|
||||
.scrollable_overflow(&physical_containing_block);
|
||||
|
||||
// https://drafts.csswg.org/css-overflow/#scrolling-direction
|
||||
// We want to clip scrollable overflow on box-start and inline-start
|
||||
// sides of the scroll container.
|
||||
//
|
||||
// FIXME(mrobinson, bug 25564): This should take into account writing
|
||||
// mode.
|
||||
let child_overflow = PhysicalRect::new(
|
||||
euclid::Point2D::zero(),
|
||||
euclid::Size2D::new(
|
||||
child_overflow.size.width + child_overflow.origin.x,
|
||||
child_overflow.size.height + child_overflow.origin.y,
|
||||
),
|
||||
);
|
||||
acc.union(&child_overflow)
|
||||
});
|
||||
// https://drafts.csswg.org/css-overflow/#scrolling-direction
|
||||
// We want to clip scrollable overflow on box-start and inline-start
|
||||
// sides of the scroll container.
|
||||
//
|
||||
// FIXME(mrobinson, bug 25564): This should take into account writing
|
||||
// mode.
|
||||
let child_overflow = PhysicalRect::new(
|
||||
euclid::Point2D::zero(),
|
||||
euclid::Size2D::new(
|
||||
child_overflow.size.width + child_overflow.origin.x,
|
||||
child_overflow.size.height + child_overflow.origin.y,
|
||||
),
|
||||
);
|
||||
acc.union(&child_overflow)
|
||||
});
|
||||
|
||||
FragmentTreeRoot {
|
||||
children: independent_layout
|
||||
.fragments
|
||||
.into_iter()
|
||||
.map(|fragment| ArcRefCell::new(fragment))
|
||||
.collect(),
|
||||
children,
|
||||
scrollable_overflow,
|
||||
initial_containing_block: physical_containing_block,
|
||||
}
|
||||
|
@ -206,7 +205,6 @@ impl FragmentTreeRoot {
|
|||
containing_block_for_all_descendants: ContainingBlock::new(
|
||||
&self.initial_containing_block,
|
||||
stacking_context_builder.current_space_and_clip,
|
||||
&self.children,
|
||||
),
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue