From e39e59ef18414a87ab6b932eae90d236884aa57f Mon Sep 17 00:00:00 2001 From: Peter Date: Wed, 10 Feb 2016 01:12:09 +0000 Subject: #1716 The indicated part of the document. Interactive test for fragid resolution. Added HTML tests for scrolling to fragid Applied algorithm from whatwg spec https://html.spec.whatwg.org/multipage/#the-indicated-part-of-the-document Changes following code review --- components/script/dom/document.rs | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'components/script/dom/document.rs') diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index a3af57b0814..de1172ed6b0 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -107,6 +107,7 @@ use style::context::ReflowGoal; use style::restyle_hints::ElementSnapshot; use style::servo::Stylesheet; use time; +use url::percent_encoding::percent_decode; use url::{Host, Url}; use util::str::{DOMString, split_html_space_chars, str_join}; @@ -515,18 +516,38 @@ impl Document { /// Attempt to find a named element in this page's document. /// https://html.spec.whatwg.org/multipage/#the-indicated-part-of-the-document pub fn find_fragment_node(&self, fragid: &str) -> Option> { - self.get_element_by_id(&Atom::from(fragid)).or_else(|| { - let check_anchor = |node: &HTMLAnchorElement| { - let elem = node.upcast::(); - elem.get_attribute(&ns!(), &atom!("name")) - .map_or(false, |attr| &**attr.value() == fragid) - }; - let doc_node = self.upcast::(); - doc_node.traverse_preorder() - .filter_map(Root::downcast) - .find(|node| check_anchor(&node)) - .map(Root::upcast) - }) + // Step 1 is not handled here; the fragid is already obtained by the calling function + // Step 2 + if fragid.is_empty() { + self.GetDocumentElement() + } else { + // Step 3 & 4 + String::from_utf8(percent_decode(fragid.as_bytes())).ok() + // Step 5 + .and_then(|decoded_fragid| self.get_element_by_id(&Atom::from(&*decoded_fragid))) + // Step 6 + .or_else(|| self.get_anchor_by_name(fragid)) + // Step 7 + .or_else(|| if fragid.to_lowercase() == "top" { + self.GetDocumentElement() + } else { + // Step 8 + None + }) + } + } + + fn get_anchor_by_name(&self, name: &str) -> Option> { + let check_anchor = |node: &HTMLAnchorElement| { + let elem = node.upcast::(); + elem.get_attribute(&ns!(), &atom!("name")) + .map_or(false, |attr| &**attr.value() == name) + }; + let doc_node = self.upcast::(); + doc_node.traverse_preorder() + .filter_map(Root::downcast) + .find(|node| check_anchor(&node)) + .map(Root::upcast) } pub fn hit_test(&self, page_point: &Point2D) -> Option { -- cgit v1.2.3