aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/fragment_tree/fragment_tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/fragment_tree/fragment_tree.rs')
-rw-r--r--components/layout/fragment_tree/fragment_tree.rs43
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>(