diff options
author | Peter <peter.hall@algomi.com> | 2016-02-10 01:12:09 +0000 |
---|---|---|
committer | Peter <peter.hall@algomi.com> | 2016-02-17 00:51:46 +0000 |
commit | e39e59ef18414a87ab6b932eae90d236884aa57f (patch) | |
tree | 38e65911524613953c8a90243fb7d518d76de6d0 /components/script | |
parent | 7aedb9c7cdcc1b67c1d6d01f36f2fe7c1a17ddac (diff) | |
download | servo-e39e59ef18414a87ab6b932eae90d236884aa57f.tar.gz servo-e39e59ef18414a87ab6b932eae90d236884aa57f.zip |
#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
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/document.rs | 45 |
1 files changed, 33 insertions, 12 deletions
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<Root<Element>> { - self.get_element_by_id(&Atom::from(fragid)).or_else(|| { - let check_anchor = |node: &HTMLAnchorElement| { - let elem = node.upcast::<Element>(); - elem.get_attribute(&ns!(), &atom!("name")) - .map_or(false, |attr| &**attr.value() == fragid) - }; - let doc_node = self.upcast::<Node>(); - 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<Root<Element>> { + let check_anchor = |node: &HTMLAnchorElement| { + let elem = node.upcast::<Element>(); + elem.get_attribute(&ns!(), &atom!("name")) + .map_or(false, |attr| &**attr.value() == name) + }; + let doc_node = self.upcast::<Node>(); + doc_node.traverse_preorder() + .filter_map(Root::downcast) + .find(|node| check_anchor(&node)) + .map(Root::upcast) } pub fn hit_test(&self, page_point: &Point2D<f32>) -> Option<UntrustedNodeAddress> { |