aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/document.rs
diff options
context:
space:
mode:
authorPu Xingyu <pu.stshine@gmail.com>2016-11-18 12:33:30 +0800
committerPu Xingyu <pu.stshine@gmail.com>2016-11-18 12:33:30 +0800
commit986314904341fafa7caa1d32ee9d992d7c45282e (patch)
tree2bd3099f84f45b782fcdf9d8170b9dc0949d453a /components/script/dom/document.rs
parenteca8f1d0b44993e8abe514612148c20b3452c6ff (diff)
downloadservo-986314904341fafa7caa1d32ee9d992d7c45282e.tar.gz
servo-986314904341fafa7caa1d32ee9d992d7c45282e.zip
Move fragment navigation into Document object
Move the `check_and_scroll_fragment()` method into Document, make the mothod set the fragment of url after navigation, and use the `perform_a_scroll()` method to scroll rather than an individual method. Also removes the broken `Window.fragment` fields.
Diffstat (limited to 'components/script/dom/document.rs')
-rw-r--r--components/script/dom/document.rs41
1 files changed, 40 insertions, 1 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 4d3513b6d96..fac64cbc965 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -18,7 +18,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter;
use dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods;
use dom::bindings::codegen::Bindings::TouchBinding::TouchMethods;
-use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, WindowMethods};
use dom::bindings::codegen::UnionTypes::NodeOrString;
use dom::bindings::error::{Error, ErrorResult, Fallible};
use dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
@@ -600,6 +600,45 @@ impl Document {
}
}
+ /// https://html.spec.whatwg.org/multipage/#scroll-to-the-fragment-identifier
+ pub fn check_and_scroll_fragment(&self, fragment: &str) {
+ let target = self.find_fragment_node(fragment);
+
+ // Step 1
+ self.set_target_element(target.r());
+
+ let point = if fragment.is_empty() || fragment.to_lowercase() == "top" {
+ // FIXME(stshine): this should be the origin of the stacking context space,
+ // which may differ under the influence of writing mode.
+ Some((0.0, 0.0))
+ } else {
+ target.r().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.
+ let rect = element.upcast::<Node>().bounding_content_box();
+
+ // 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.
+ (rect.origin.x.to_nearest_px() as f32,
+ rect.origin.y.to_nearest_px() as f32)
+ })
+ };
+
+ if let Some((x, y)) = point {
+ // Step 3
+ self.window.perform_a_scroll(x, y, ScrollBehavior::Instant,
+ target.r());
+ }
+ }
+
fn get_anchor_by_name(&self, name: &str) -> Option<Root<Element>> {
let check_anchor = |node: &HTMLAnchorElement| {
let elem = node.upcast::<Element>();