aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlanchorelement.rs
diff options
context:
space:
mode:
authorJaydeep <jd.ramani111@gmail.com>2016-01-03 17:14:30 -0800
committerJonathan Schuster <jonathan.p.schuster@gmail.com>2016-03-24 21:14:28 -0400
commitc96c26b4f759c07e32109c73e8b434c3250b8fd7 (patch)
treec8b7c106ba74d03400ca1ac9c6e56336f419b926 /components/script/dom/htmlanchorelement.rs
parent446783f7b6f0b55164b3b3c3e8be90c2b392cf97 (diff)
downloadservo-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.rs343
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 {