diff options
Diffstat (limited to 'components/layout/fragment_tree')
-rw-r--r-- | components/layout/fragment_tree/base_fragment.rs | 6 | ||||
-rw-r--r-- | components/layout/fragment_tree/box_fragment.rs | 18 | ||||
-rw-r--r-- | components/layout/fragment_tree/fragment.rs | 27 | ||||
-rw-r--r-- | components/layout/fragment_tree/fragment_tree.rs | 56 | ||||
-rw-r--r-- | components/layout/fragment_tree/positioning_fragment.rs | 17 |
5 files changed, 90 insertions, 34 deletions
diff --git a/components/layout/fragment_tree/base_fragment.rs b/components/layout/fragment_tree/base_fragment.rs index 0cf6ee511cb..ff5df44c225 100644 --- a/components/layout/fragment_tree/base_fragment.rs +++ b/components/layout/fragment_tree/base_fragment.rs @@ -32,10 +32,8 @@ impl BaseFragment { } } - /// Returns true if this fragment is non-anonymous and it is for the given - /// OpaqueNode, regardless of the pseudo element. - pub(crate) fn is_for_node(&self, node: OpaqueNode) -> bool { - self.tag.map(|tag| tag.node == node).unwrap_or(false) + pub(crate) fn is_anonymous(&self) -> bool { + self.tag.is_none() } } diff --git a/components/layout/fragment_tree/box_fragment.rs b/components/layout/fragment_tree/box_fragment.rs index 65ad1c4aa93..9b96b1c4fb4 100644 --- a/components/layout/fragment_tree/box_fragment.rs +++ b/components/layout/fragment_tree/box_fragment.rs @@ -16,7 +16,8 @@ use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::specified::box_::DisplayOutside; -use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment}; +use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment, FragmentFlags}; +use crate::SharedStyle; use crate::display_list::ToWebRender; use crate::formatting_contexts::Baselines; use crate::geom::{ @@ -39,11 +40,9 @@ pub(crate) enum BackgroundMode { /// Draw the background normally, getting information from the Fragment style. Normal, } - #[derive(MallocSizeOf)] pub(crate) struct ExtraBackground { - #[conditional_malloc_size_of] - pub style: ServoArc<ComputedValues>, + pub style: SharedStyle, pub rect: PhysicalRect<Au>, } @@ -59,7 +58,6 @@ pub(crate) enum SpecificLayoutInfo { pub(crate) struct BoxFragment { pub base: BaseFragment, - #[conditional_malloc_size_of] pub style: ServoArc<ComputedValues>, pub children: Vec<Fragment>, @@ -238,6 +236,16 @@ impl BoxFragment { self.margin + self.border + self.padding } + pub(crate) fn is_root_element(&self) -> bool { + self.base.flags.intersects(FragmentFlags::IS_ROOT_ELEMENT) + } + + pub(crate) fn is_body_element_of_html_element_root(&self) -> bool { + self.base + .flags + .intersects(FragmentFlags::IS_BODY_ELEMENT_OF_HTML_ELEMENT_ROOT) + } + pub fn print(&self, tree: &mut PrintTree) { tree.new_level(format!( "Box\ diff --git a/components/layout/fragment_tree/fragment.rs b/components/layout/fragment_tree/fragment.rs index 1c5324fa1c4..1ebc7b3c989 100644 --- a/components/layout/fragment_tree/fragment.rs +++ b/components/layout/fragment_tree/fragment.rs @@ -22,6 +22,7 @@ use super::{ Tag, }; use crate::cell::ArcRefCell; +use crate::flow::inline::SharedInlineStyles; use crate::geom::{LogicalSides, PhysicalPoint, PhysicalRect}; use crate::style_ext::ComputedValuesExt; @@ -64,8 +65,7 @@ pub(crate) struct CollapsedMargin { #[derive(MallocSizeOf)] pub(crate) struct TextFragment { pub base: BaseFragment, - #[conditional_malloc_size_of] - pub parent_style: ServoArc<ComputedValues>, + pub inline_styles: SharedInlineStyles, pub rect: PhysicalRect<Au>, pub font_metrics: FontMetrics, pub font_key: FontInstanceKey, @@ -78,14 +78,11 @@ pub(crate) struct TextFragment { /// Extra space to add for each justification opportunity. pub justification_adjustment: Au, pub selection_range: Option<ServoRange<ByteIndex>>, - #[conditional_malloc_size_of] - pub selected_style: ServoArc<ComputedValues>, } #[derive(MallocSizeOf)] pub(crate) struct ImageFragment { pub base: BaseFragment, - #[conditional_malloc_size_of] pub style: ServoArc<ComputedValues>, pub rect: PhysicalRect<Au>, pub clip: PhysicalRect<Au>, @@ -97,7 +94,6 @@ pub(crate) struct IFrameFragment { pub base: BaseFragment, pub pipeline_id: PipelineId, pub rect: PhysicalRect<Au>, - #[conditional_malloc_size_of] pub style: ServoArc<ComputedValues>, } @@ -308,6 +304,25 @@ impl Fragment { _ => None, } } + + pub(crate) fn repair_style(&self, style: &ServoArc<ComputedValues>) { + match self { + Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => { + box_fragment.borrow_mut().style = style.clone() + }, + Fragment::Positioning(positioning_fragment) => { + positioning_fragment.borrow_mut().style = style.clone(); + }, + Fragment::AbsoluteOrFixedPositioned(positioned_fragment) => { + if let Some(ref fragment) = positioned_fragment.borrow().fragment { + fragment.repair_style(style); + } + }, + Fragment::Text(..) => unreachable!("Should never try to repair style of TextFragment"), + Fragment::Image(image_fragment) => image_fragment.borrow_mut().style = style.clone(), + Fragment::IFrame(iframe_fragment) => iframe_fragment.borrow_mut().style = style.clone(), + } + } } impl TextFragment { 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) + } } diff --git a/components/layout/fragment_tree/positioning_fragment.rs b/components/layout/fragment_tree/positioning_fragment.rs index 0cf525a3479..e45a6137bff 100644 --- a/components/layout/fragment_tree/positioning_fragment.rs +++ b/components/layout/fragment_tree/positioning_fragment.rs @@ -24,9 +24,8 @@ pub(crate) struct PositioningFragment { /// The scrollable overflow of this anonymous fragment's children. pub scrollable_overflow: PhysicalRect<Au>, - /// If this fragment was created with a style, the style of the fragment. - #[conditional_malloc_size_of] - pub style: Option<ServoArc<ComputedValues>>, + /// The style of the fragment. + pub style: ServoArc<ComputedValues>, /// This [`PositioningFragment`]'s containing block rectangle in coordinates relative to /// the initial containing block, but not taking into account any transforms. @@ -34,8 +33,12 @@ pub(crate) struct PositioningFragment { } impl PositioningFragment { - pub fn new_anonymous(rect: PhysicalRect<Au>, children: Vec<Fragment>) -> ArcRefCell<Self> { - Self::new_with_base_fragment(BaseFragment::anonymous(), None, rect, children) + pub fn new_anonymous( + style: ServoArc<ComputedValues>, + rect: PhysicalRect<Au>, + children: Vec<Fragment>, + ) -> ArcRefCell<Self> { + Self::new_with_base_fragment(BaseFragment::anonymous(), style, rect, children) } pub fn new_empty( @@ -43,12 +46,12 @@ impl PositioningFragment { rect: PhysicalRect<Au>, style: ServoArc<ComputedValues>, ) -> ArcRefCell<Self> { - Self::new_with_base_fragment(base_fragment_info.into(), Some(style), rect, Vec::new()) + Self::new_with_base_fragment(base_fragment_info.into(), style, rect, Vec::new()) } fn new_with_base_fragment( base: BaseFragment, - style: Option<ServoArc<ComputedValues>>, + style: ServoArc<ComputedValues>, rect: PhysicalRect<Au>, children: Vec<Fragment>, ) -> ArcRefCell<Self> { |