mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Fix several bugs related to scrolling
* scrollLeft/scrollTop returned values of parent or even document root Only the scroll of the node itself is returned. Otherwise 0.0. * Scrolling via script had set viewport. This resulted in other nodes appearing scrolled. Now scroll_offsets are updated with correct node id. These bugs caused other odd behavior like both body and document.documentElement being scrolled or the view for scrolled elements jumping.
This commit is contained in:
parent
effd6f2f87
commit
284cb8aae8
6 changed files with 33 additions and 25 deletions
|
@ -703,6 +703,7 @@ impl Document {
|
|||
// Step 3
|
||||
let global_scope = self.window.upcast::<GlobalScope>();
|
||||
let webrender_pipeline_id = global_scope.pipeline_id().to_webrender();
|
||||
self.window.update_viewport_for_scroll(x, y);
|
||||
self.window.perform_a_scroll(x,
|
||||
y,
|
||||
ClipId::root_scroll_node(webrender_pipeline_id),
|
||||
|
|
|
@ -1356,7 +1356,7 @@ impl Element {
|
|||
// Step 10 (TODO)
|
||||
|
||||
// Step 11
|
||||
win.scroll_node(node.to_trusted_node_address(), x, y, behavior);
|
||||
win.scroll_node(node, x, y, behavior);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/DOM-Parsing/#parsing
|
||||
|
@ -1794,7 +1794,7 @@ impl ElementMethods for Element {
|
|||
// Step 10 (TODO)
|
||||
|
||||
// Step 11
|
||||
win.scroll_node(node.to_trusted_node_address(), self.ScrollLeft(), y, behavior);
|
||||
win.scroll_node(node, self.ScrollLeft(), y, behavior);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrolltop
|
||||
|
@ -1887,7 +1887,7 @@ impl ElementMethods for Element {
|
|||
// Step 10 (TODO)
|
||||
|
||||
// Step 11
|
||||
win.scroll_node(node.to_trusted_node_address(), x, self.ScrollTop(), behavior);
|
||||
win.scroll_node(node, x, self.ScrollTop(), behavior);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scrollwidth
|
||||
|
|
|
@ -13,7 +13,6 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
|||
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnBeforeUnloadEventHandlerNonNull;
|
||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
|
||||
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionState;
|
||||
use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
|
||||
use dom::bindings::codegen::Bindings::WindowBinding::{self, FrameRequestCallback, WindowMethods};
|
||||
|
@ -1126,8 +1125,11 @@ impl Window {
|
|||
//let document = self.Document();
|
||||
// Step 12
|
||||
let global_scope = self.upcast::<GlobalScope>();
|
||||
self.perform_a_scroll(x.to_f32().unwrap_or(0.0f32),
|
||||
y.to_f32().unwrap_or(0.0f32),
|
||||
let x = x.to_f32().unwrap_or(0.0f32);
|
||||
let y = y.to_f32().unwrap_or(0.0f32);
|
||||
self.update_viewport_for_scroll(x, y);
|
||||
self.perform_a_scroll(x,
|
||||
y,
|
||||
global_scope.pipeline_id().root_scroll_node(),
|
||||
behavior,
|
||||
None);
|
||||
|
@ -1158,9 +1160,6 @@ impl Window {
|
|||
scroll_offset: Vector2D::new(-x, -y),
|
||||
})).unwrap();
|
||||
|
||||
// TODO (farodin91): Raise an event to stop the current_viewport
|
||||
self.update_viewport_for_scroll(x, y);
|
||||
|
||||
let global_scope = self.upcast::<GlobalScope>();
|
||||
let message = ConstellationMsg::ScrollFragmentPoint(scroll_root_id, point, smooth);
|
||||
global_scope.constellation_chan().send(message).unwrap();
|
||||
|
@ -1450,33 +1449,32 @@ impl Window {
|
|||
}
|
||||
|
||||
pub fn scroll_offset_query(&self, node: &Node) -> Vector2D<f32> {
|
||||
let mut node = Root::from_ref(node);
|
||||
loop {
|
||||
if let Some(scroll_offset) = self.scroll_offsets
|
||||
.borrow()
|
||||
.get(&node.to_untrusted_node_address()) {
|
||||
return *scroll_offset
|
||||
}
|
||||
node = match node.GetParentNode() {
|
||||
Some(node) => node,
|
||||
None => break,
|
||||
}
|
||||
if let Some(scroll_offset) = self.scroll_offsets
|
||||
.borrow()
|
||||
.get(&node.to_untrusted_node_address()) {
|
||||
return *scroll_offset
|
||||
}
|
||||
let vp_origin = self.current_viewport.get().origin;
|
||||
Vector2D::new(vp_origin.x.to_f32_px(), vp_origin.y.to_f32_px())
|
||||
Vector2D::new(0.0, 0.0)
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-element-scroll
|
||||
pub fn scroll_node(&self,
|
||||
node: TrustedNodeAddress,
|
||||
node: &Node,
|
||||
x_: f64,
|
||||
y_: f64,
|
||||
behavior: ScrollBehavior) {
|
||||
if !self.reflow(ReflowGoal::ForScriptQuery,
|
||||
ReflowQueryType::NodeScrollRootIdQuery(node),
|
||||
ReflowQueryType::NodeScrollRootIdQuery(node.to_trusted_node_address()),
|
||||
ReflowReason::Query) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The scroll offsets are immediatly updated since later calls
|
||||
// to topScroll and others may access the properties before
|
||||
// webrender has a chance to update the offsets.
|
||||
self.scroll_offsets.borrow_mut().insert(node.to_untrusted_node_address(),
|
||||
Vector2D::new(x_ as f32, y_ as f32));
|
||||
|
||||
let NodeScrollRootIdResponse(scroll_root_id) = self.layout_rpc.node_scroll_root_id();
|
||||
|
||||
// Step 12
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue