aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/fragment_tree
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/fragment_tree')
-rw-r--r--components/layout/fragment_tree/base_fragment.rs6
-rw-r--r--components/layout/fragment_tree/box_fragment.rs18
-rw-r--r--components/layout/fragment_tree/fragment.rs27
-rw-r--r--components/layout/fragment_tree/fragment_tree.rs56
-rw-r--r--components/layout/fragment_tree/positioning_fragment.rs17
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> {