diff options
Diffstat (limited to 'components/layout_2020/flow/root.rs')
-rw-r--r-- | components/layout_2020/flow/root.rs | 107 |
1 files changed, 36 insertions, 71 deletions
diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 7da70b8715a..adbcb26d4c9 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -38,7 +38,7 @@ pub struct BoxTreeRoot(BlockFormattingContext); #[derive(Serialize)] pub struct FragmentTreeRoot { /// The children of the root of the fragment tree. - children: Vec<Fragment>, + children: Vec<ArcRefCell<Fragment>>, /// The scrollable overflow of the root of the fragment tree. scrollable_overflow: PhysicalRect<Length>, @@ -147,44 +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, + children, scrollable_overflow, initial_containing_block: physical_containing_block, } @@ -202,12 +205,12 @@ impl FragmentTreeRoot { containing_block_for_all_descendants: ContainingBlock::new( &self.initial_containing_block, stacking_context_builder.current_space_and_clip, - &self.children, ), }; for fragment in &self.children { - fragment.build_stacking_context_tree( + fragment.borrow().build_stacking_context_tree( + fragment, &mut stacking_context_builder, &containing_block_info, &mut stacking_context, @@ -223,7 +226,7 @@ impl FragmentTreeRoot { pub fn print(&self) { let mut print_tree = PrintTree::new("Fragment Tree".to_string()); for fragment in &self.children { - fragment.print(&mut print_tree); + fragment.borrow().print(&mut print_tree); } } @@ -238,49 +241,11 @@ impl FragmentTreeRoot { &self, mut process_func: impl FnMut(&Fragment, &PhysicalRect<Length>) -> Option<T>, ) -> Option<T> { - fn recur<T>( - fragments: &[Fragment], - containing_block: &PhysicalRect<Length>, - process_func: &mut impl FnMut(&Fragment, &PhysicalRect<Length>) -> Option<T>, - ) -> Option<T> { - for fragment in fragments { - if let Some(result) = process_func(fragment, containing_block) { - return Some(result); - } - - match fragment { - Fragment::Box(fragment) => { - let new_containing_block = fragment - .content_rect - .to_physical(fragment.style.writing_mode, containing_block) - .translate(containing_block.origin.to_vector()); - if let Some(result) = - recur(&fragment.children, &new_containing_block, process_func) - { - return Some(result); - } - }, - Fragment::Anonymous(fragment) => { - let new_containing_block = fragment - .rect - .to_physical(fragment.mode, containing_block) - .translate(containing_block.origin.to_vector()); - if let Some(result) = - recur(&fragment.children, &new_containing_block, process_func) - { - return Some(result); - } - }, - _ => {}, - } - } - None - } - recur( - &self.children, - &self.initial_containing_block, - &mut process_func, - ) + self.children.iter().find_map(|child| { + child + .borrow() + .find(&self.initial_containing_block, &mut process_func) + }) } pub fn get_content_box_for_node(&self, requested_node: OpaqueNode) -> Rect<Au> { |