Refactor scrolls on the window object (#29680)

Refactor the scrolling and scrollable area calculation on the window
object, to make it better match the specification. This has some mild
changes to behavior, but in general things work the same as they did
before. This is mainly preparation for properly handling viewport
propagation of the `overflow` property but seems to fix a few issues as
well.

There is one new failure in Layout 2020 regarding `position: sticky`,
but this isn't a big deal because there is no support for `position:
sticky` in Layout 2020 yet.

Co-authored-by: Rakhi Sharma <atbrakhi@igalia.com>
This commit is contained in:
Martin Robinson 2023-09-15 12:57:54 +02:00 committed by GitHub
parent 0b86d65798
commit abca586e0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 128 additions and 118 deletions

View file

@ -167,6 +167,15 @@ impl Fragment {
}
}
pub fn scrolling_area(&self, containing_block: &PhysicalRect<Length>) -> PhysicalRect<Length> {
match self {
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment
.scrollable_overflow(containing_block)
.translate(containing_block.origin.to_vector()),
_ => self.scrollable_overflow(containing_block),
}
}
pub fn scrollable_overflow(
&self,
containing_block: &PhysicalRect<Length>,

View file

@ -172,36 +172,26 @@ impl FragmentTree {
.unwrap_or_else(Rect::zero)
}
pub fn get_scroll_area_for_node(&self, requested_node: OpaqueNode) -> Rect<i32> {
let mut scroll_area: PhysicalRect<Length> = PhysicalRect::zero();
pub fn get_scrolling_area_for_viewport(&self) -> PhysicalRect<Length> {
let mut scroll_area = self.initial_containing_block;
for fragment in self.root_fragments.iter() {
scroll_area = fragment
.borrow()
.scrolling_area(&self.initial_containing_block)
.union(&scroll_area);
}
scroll_area
}
pub fn get_scrolling_area_for_node(&self, requested_node: OpaqueNode) -> PhysicalRect<Length> {
let tag_to_find = Tag::new(requested_node);
self.find(|fragment, _, containing_block| {
if fragment.tag() != Some(tag_to_find) {
return None::<()>;
let scroll_area = self.find(|fragment, _, containing_block| {
if fragment.tag() == Some(tag_to_find) {
Some(fragment.scrolling_area(&containing_block))
} else {
None
}
scroll_area = match fragment {
Fragment::Box(fragment) | Fragment::Float(fragment) => fragment
.scrollable_overflow(&containing_block)
.translate(containing_block.origin.to_vector()),
Fragment::Text(_) |
Fragment::AbsoluteOrFixedPositioned(_) |
Fragment::Image(_) |
Fragment::IFrame(_) |
Fragment::Anonymous(_) => return None,
};
None::<()>
});
Rect::new(
Point2D::new(
scroll_area.origin.x.px() as i32,
scroll_area.origin.y.px() as i32,
),
Size2D::new(
scroll_area.size.width.px() as i32,
scroll_area.size.height.px() as i32,
),
)
scroll_area.unwrap_or_else(PhysicalRect::<Length>::zero)
}
}