diff options
Diffstat (limited to 'components/layout/fragment_tree/fragment_tree.rs')
-rw-r--r-- | components/layout/fragment_tree/fragment_tree.rs | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/components/layout/fragment_tree/fragment_tree.rs b/components/layout/fragment_tree/fragment_tree.rs index 1499a50dacf..979bd0090fc 100644 --- a/components/layout/fragment_tree/fragment_tree.rs +++ b/components/layout/fragment_tree/fragment_tree.rs @@ -11,10 +11,10 @@ use malloc_size_of_derive::MallocSizeOf; use style::animation::AnimationSetKey; use webrender_api::units; -use super::{ContainingBlockManager, Fragment}; +use super::{BoxFragment, ContainingBlockManager, Fragment}; +use crate::ArcRefCell; use crate::context::LayoutContext; use crate::display_list::StackingContext; -use crate::flow::CanvasBackground; use crate::geom::PhysicalRect; #[derive(MallocSizeOf)] @@ -36,9 +36,6 @@ pub struct FragmentTree { /// The containing block used in the layout of this fragment tree. pub(crate) initial_containing_block: PhysicalRect<Au>, - /// <https://drafts.csswg.org/css-backgrounds/#special-backgrounds> - pub(crate) canvas_background: CanvasBackground, - /// Whether or not the viewport is sensitive to scroll input events. pub viewport_scroll_sensitivity: AxesScrollSensitivity, } @@ -49,14 +46,12 @@ impl FragmentTree { root_fragments: Vec<Fragment>, scrollable_overflow: PhysicalRect<Au>, initial_containing_block: PhysicalRect<Au>, - canvas_background: CanvasBackground, viewport_scroll_sensitivity: AxesScrollSensitivity, ) -> Self { let fragment_tree = Self { root_fragments, scrollable_overflow, initial_containing_block, - canvas_background, viewport_scroll_sensitivity, }; @@ -102,11 +97,7 @@ impl FragmentTree { root_stacking_context: &StackingContext, ) { // Paint the canvas’ background (if any) before/under everything else - root_stacking_context.build_canvas_background_display_list( - builder, - self, - &self.initial_containing_block, - ); + root_stacking_context.build_canvas_background_display_list(builder, self); root_stacking_context.build_display_list(builder); } @@ -160,4 +151,45 @@ impl FragmentTree { scroll_area } } + + /// Find the `<body>` element's [`Fragment`], if it exists in this [`FragmentTree`]. + pub(crate) fn body_fragment(&self) -> Option<ArcRefCell<BoxFragment>> { + fn find_body(children: &[Fragment]) -> Option<ArcRefCell<BoxFragment>> { + children.iter().find_map(|fragment| { + match fragment { + Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => { + let borrowed_box_fragment = box_fragment.borrow(); + if borrowed_box_fragment.is_body_element_of_html_element_root() { + return Some(box_fragment.clone()); + } + + // The fragment for the `<body>` element is typically a child of the root (though, + // not if it's absolutely positioned), so we need to recurse into the children of + // the root to find it. + // + // Additionally, recurse into any anonymous fragments, as the `<body>` fragment may + // have created anonymous parents (for instance by creating an inline formatting context). + if borrowed_box_fragment.is_root_element() || + borrowed_box_fragment.base.is_anonymous() + { + find_body(&borrowed_box_fragment.children) + } else { + None + } + }, + Fragment::Positioning(positioning_context) + if positioning_context.borrow().base.is_anonymous() => + { + // If the `<body>` element is a `display: inline` then it might be nested inside of a + // `PositioningFragment` for the purposes of putting it on the first line of the implied + // inline formatting context. + find_body(&positioning_context.borrow().children) + }, + _ => None, + } + }) + } + + find_body(&self.root_fragments) + } } |