diff options
author | Jaydeep <jd.ramani111@gmail.com> | 2016-01-03 17:14:30 -0800 |
---|---|---|
committer | Jonathan Schuster <jonathan.p.schuster@gmail.com> | 2016-03-24 21:14:28 -0400 |
commit | c96c26b4f759c07e32109c73e8b434c3250b8fd7 (patch) | |
tree | c8b7c106ba74d03400ca1ac9c6e56336f419b926 /components/script/dom/htmlanchorelement.rs | |
parent | 446783f7b6f0b55164b3b3c3e8be90c2b392cf97 (diff) | |
download | servo-c96c26b4f759c07e32109c73e8b434c3250b8fd7.tar.gz servo-c96c26b4f759c07e32109c73e8b434c3250b8fd7.zip |
Implement HTMLHyperlinkElementUtils for HTMLAnchorElement
Diffstat (limited to 'components/script/dom/htmlanchorelement.rs')
-rw-r--r-- | components/script/dom/htmlanchorelement.rs | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 0a1e15ef193..16f47315b76 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -5,6 +5,7 @@ use dom::activation::Activatable; use dom::attr::AttrValue; +use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods; use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding; use dom::bindings::codegen::Bindings::HTMLAnchorElementBinding::HTMLAnchorElementMethods; @@ -12,6 +13,7 @@ use dom::bindings::codegen::Bindings::MouseEventBinding::MouseEventMethods; use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, MutNullableHeap, Root}; +use dom::bindings::str::USVString; use dom::document::Document; use dom::domtokenlist::DOMTokenList; use dom::element::Element; @@ -21,16 +23,19 @@ use dom::htmlelement::HTMLElement; use dom::htmlimageelement::HTMLImageElement; use dom::mouseevent::MouseEvent; use dom::node::{Node, document_from_node, window_from_node}; +use dom::urlhelper::UrlHelper; use dom::virtualmethods::VirtualMethods; use num::ToPrimitive; use std::default::Default; use string_cache::Atom; +use url::{Url, UrlParser}; use util::str::DOMString; #[dom_struct] pub struct HTMLAnchorElement { htmlelement: HTMLElement, rel_list: MutNullableHeap<JS<DOMTokenList>>, + url: DOMRefCell<Option<Url>>, } impl HTMLAnchorElement { @@ -41,6 +46,7 @@ impl HTMLAnchorElement { htmlelement: HTMLElement::new_inherited(localName, prefix, document), rel_list: Default::default(), + url: DOMRefCell::new(None), } } @@ -51,6 +57,37 @@ impl HTMLAnchorElement { let element = HTMLAnchorElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLAnchorElementBinding::Wrap) } + + // https://html.spec.whatwg.org/multipage/#concept-hyperlink-url-set + fn set_url(&self) { + let attribute = self.upcast::<Element>().get_attribute(&ns!(), &atom!("href")); + *self.url.borrow_mut() = attribute.and_then(|attribute| { + let document = document_from_node(self); + let mut parser = UrlParser::new(); + parser.base_url(document.url()); + parser.parse(&attribute.value()).ok() + }); + } + + // https://html.spec.whatwg.org/multipage/#reinitialise-url + fn reinitialize_url(&self) { + // Step 1. + match *self.url.borrow() { + None => return, + Some(ref url) if url.scheme == "blob" && + url.non_relative_scheme_data().is_some() => return, + _ => (), + } + + // Step 2. + self.set_url(); + } + + // https://html.spec.whatwg.org/multipage/#update-href + fn update_href(&self) { + self.upcast::<Element>().set_string_attribute(&atom!("href"), + self.url.borrow().as_ref().unwrap().serialize().into()); + } } impl VirtualMethods for HTMLAnchorElement { @@ -107,6 +144,312 @@ impl HTMLAnchorElementMethods for HTMLAnchorElement { // https://html.spec.whatwg.org/multipage/#dom-a-shape make_setter!(SetShape, "shape"); + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash + fn Hash(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 3. + None => USVString(String::new()), + Some(ref url) => { + // Steps 3-4. + UrlHelper::Hash(url) + } + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hash + fn SetHash(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.scheme == "javascript" { return; } + // Steps 4-5. + UrlHelper::SetHash(url, value); + // Step 6. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-host + fn Host(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 3. + None => USVString(String::new()), + Some(ref url) => { + if url.host().is_none() { + USVString(String::new()) + } else { + // Steps 4-5. + UrlHelper::Host(url) + } + } + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-host + fn SetHost(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.non_relative_scheme_data().is_some() { + return; + } + // Step 4. + UrlHelper::SetHost(url, value); + // Step 5. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname + fn Hostname(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 3. + None => USVString(String::new()), + Some(ref url) => { + // Step 4. + UrlHelper::Hostname(url) + } + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-hostname + fn SetHostname(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.non_relative_scheme_data().is_some() { + return; + } + // Step 4. + UrlHelper::SetHostname(url, value); + // Step 5. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href + fn Href(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + USVString(match *self.url.borrow() { + None => { + match self.upcast::<Element>().get_attribute(&ns!(), &atom!("href")) { + // Step 3. + None => String::new(), + // Step 4. + Some(attribute) => (**attribute.value()).to_owned(), + } + }, + // Step 5. + Some(ref url) => url.serialize(), + }) + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href + fn SetHref(&self, value: USVString) { + self.upcast::<Element>().set_string_attribute(&atom!("href"), + DOMString::from_string(value.0)); + self.set_url(); + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-password + fn Password(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 3. + None => USVString(String::new()), + // Steps 3-4. + Some(ref url) => UrlHelper::Password(url) + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-password + fn SetPassword(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.host().is_none() || url.non_relative_scheme_data().is_some() { + return; + } + // Step 4. + UrlHelper::SetPassword(url, value); + // Step 5. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname + fn Pathname(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 3. + None => USVString(String::new()), + // Steps 4-5. + Some(ref url) => UrlHelper::Pathname(url) + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-pathname + fn SetPathname(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.non_relative_scheme_data().is_some() { return; } + // Step 5. + UrlHelper::SetPathname(url, value); + // Step 6. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-port + fn Port(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 3. + None => USVString(String::new()), + // Step 4. + Some(ref url) => UrlHelper::Port(url) + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-port + fn SetPort(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.host().is_none() || + url.non_relative_scheme_data().is_some() || + url.scheme == "file" { + return; + } + // Step 4. + UrlHelper::SetPort(url, value); + // Step 5. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol + fn Protocol(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 2. + None => USVString(":".to_owned()), + // Step 3. + Some(ref url) => UrlHelper::Protocol(url) + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-protocol + fn SetProtocol(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 2. + if let Some(url) = self.url.borrow_mut().as_mut() { + // Step 3. + UrlHelper::SetProtocol(url, value); + // Step 4. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-search + fn Search(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 2. + None => USVString(String::new()), + // Step 3. + Some(ref url) => UrlHelper::Search(url) + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-search + fn SetSearch(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + // Steps 4-5. + // TODO add this element's node document character encoding as + // encoding override (as described in the spec) + UrlHelper::SetSearch(url, value); + // Step 6. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-username + fn Username(&self) -> USVString { + // Step 1. + self.reinitialize_url(); + + match *self.url.borrow() { + // Step 2. + None => USVString(String::new()), + // Step 3. + Some(ref url) => UrlHelper::Username(url) + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-username + fn SetUsername(&self, value: USVString) { + // Step 1. + self.reinitialize_url(); + + // Step 3. + if let Some(url) = self.url.borrow_mut().as_mut() { + if url.host().is_none() || url.non_relative_scheme_data().is_some() { + return; + } + + // Step 4. + UrlHelper::SetUsername(url, value); + // Step 5. + self.update_href(); + } + } + + // https://html.spec.whatwg.org/multipage/#dom-hyperlink-href + fn Stringifier(&self) -> DOMString { + DOMString::from(self.Href().0) + } } impl Activatable for HTMLAnchorElement { |