mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
script: Prevent "scroll to fragment" from scrolling offscreen (#32129)
Previously, the "scroll to fragment" operation could scroll past the end of the screen, because the scroll position was not clamped to viewport boundaries. Correct this by using the `Window::scroll()` method which handles this case. In addition, ensure that `Window`'s `current_viewport` member is initialized properly when it is created.
This commit is contained in:
parent
bef6c295aa
commit
1440406e91
6 changed files with 60 additions and 20 deletions
|
@ -980,21 +980,20 @@ impl Document {
|
|||
let point = target
|
||||
.as_ref()
|
||||
.map(|element| {
|
||||
// FIXME(#8275, pcwalton): This is pretty bogus when multiple layers are involved.
|
||||
// Really what needs to happen is that this needs to go through layout to ask which
|
||||
// layer the element belongs to, and have it send the scroll message to the
|
||||
// compositor.
|
||||
// TODO: This strategy is completely wrong if the element we are scrolling to in
|
||||
// inside other scrollable containers. Ideally this should use an implementation of
|
||||
// `scrollIntoView` when that is available:
|
||||
// See https://github.com/servo/servo/issues/24059.
|
||||
let rect = element.upcast::<Node>().bounding_content_box_or_zero();
|
||||
|
||||
// In order to align with element edges, we snap to unscaled pixel boundaries, since
|
||||
// the paint thread currently does the same for drawing elements. This is important
|
||||
// for pages that require pixel perfect scroll positioning for proper display
|
||||
// (like Acid2). Since we don't have the device pixel ratio here, this might not be
|
||||
// accurate, but should work as long as the ratio is a whole number. Once #8275 is
|
||||
// fixed this should actually take into account the real device pixel ratio.
|
||||
// (like Acid2).
|
||||
let device_pixel_ratio = self.window.device_pixel_ratio().get();
|
||||
(
|
||||
rect.origin.x.to_nearest_px() as f32,
|
||||
rect.origin.y.to_nearest_px() as f32,
|
||||
rect.origin.x.to_nearest_pixel(device_pixel_ratio) as f32,
|
||||
rect.origin.y.to_nearest_pixel(device_pixel_ratio) as f32,
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
|
@ -1008,16 +1007,8 @@ impl Document {
|
|||
});
|
||||
|
||||
if let Some((x, y)) = point {
|
||||
// Step 3
|
||||
let global_scope = self.window.upcast::<GlobalScope>();
|
||||
self.window.update_viewport_for_scroll(x, y);
|
||||
self.window.perform_a_scroll(
|
||||
x,
|
||||
y,
|
||||
global_scope.pipeline_id().root_scroll_id(),
|
||||
ScrollBehavior::Instant,
|
||||
target.as_deref(),
|
||||
);
|
||||
self.window
|
||||
.scroll(x as f64, y as f64, ScrollBehavior::Instant)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue