diff options
author | Pu Xingyu <pu.stshine@gmail.com> | 2016-11-18 12:33:30 +0800 |
---|---|---|
committer | Pu Xingyu <pu.stshine@gmail.com> | 2016-11-18 12:33:30 +0800 |
commit | 986314904341fafa7caa1d32ee9d992d7c45282e (patch) | |
tree | 2bd3099f84f45b782fcdf9d8170b9dc0949d453a /components/script/dom/document.rs | |
parent | eca8f1d0b44993e8abe514612148c20b3452c6ff (diff) | |
download | servo-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.rs | 41 |
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>(); |