diff options
Diffstat (limited to 'components/layout/fragment_tree/fragment_tree.rs')
-rw-r--r-- | components/layout/fragment_tree/fragment_tree.rs | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/components/layout/fragment_tree/fragment_tree.rs b/components/layout/fragment_tree/fragment_tree.rs index ba03a72ac21..b59ace43aa6 100644 --- a/components/layout/fragment_tree/fragment_tree.rs +++ b/components/layout/fragment_tree/fragment_tree.rs @@ -2,14 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use std::cell::Cell; + use app_units::Au; use base::print_tree::PrintTree; use compositing_traits::display_list::AxesScrollSensitivity; -use euclid::default::Size2D; use fxhash::FxHashSet; use malloc_size_of_derive::MallocSizeOf; use style::animation::AnimationSetKey; -use webrender_api::units; use super::{BoxFragment, ContainingBlockManager, Fragment}; use crate::ArcRefCell; @@ -30,7 +30,7 @@ pub struct FragmentTree { /// The scrollable overflow rectangle for the entire tree /// <https://drafts.csswg.org/css-overflow/#scrollable> - pub(crate) scrollable_overflow: PhysicalRect<Au>, + scrollable_overflow: Cell<Option<PhysicalRect<Au>>>, /// The containing block used in the layout of this fragment tree. pub(crate) initial_containing_block: PhysicalRect<Au>, @@ -43,13 +43,12 @@ impl FragmentTree { pub(crate) fn new( layout_context: &LayoutContext, root_fragments: Vec<Fragment>, - scrollable_overflow: PhysicalRect<Au>, initial_containing_block: PhysicalRect<Au>, viewport_scroll_sensitivity: AxesScrollSensitivity, ) -> Self { let fragment_tree = Self { root_fragments, - scrollable_overflow, + scrollable_overflow: Cell::default(), initial_containing_block, viewport_scroll_sensitivity, }; @@ -97,11 +96,35 @@ impl FragmentTree { } } - pub fn scrollable_overflow(&self) -> units::LayoutSize { - units::LayoutSize::from_untyped(Size2D::new( - self.scrollable_overflow.size.width.to_f32_px(), - self.scrollable_overflow.size.height.to_f32_px(), - )) + pub(crate) fn scrollable_overflow(&self) -> PhysicalRect<Au> { + self.scrollable_overflow + .get() + .expect("Should only call `scrollable_overflow()` after calculating overflow") + } + + pub(crate) fn calculate_scrollable_overflow(&self) { + self.scrollable_overflow + .set(Some(self.root_fragments.iter().fold( + PhysicalRect::zero(), + |acc, child| { + let child_overflow = child.calculate_scrollable_overflow_for_parent(); + + // 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) + }, + ))); } pub(crate) fn find<T>( |