1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use dom::bindings::codegen::Bindings::LocationBinding; 6 use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods; 7 use dom::bindings::codegen::Bindings::WindowBinding::WindowBinding::WindowMethods; 8 use dom::bindings::error::{Error, ErrorResult, Fallible}; 9 use dom::bindings::reflector::{Reflector, reflect_dom_object}; 10 use dom::bindings::root::{Dom, DomRoot}; 11 use dom::bindings::str::{DOMString, USVString}; 12 use dom::globalscope::GlobalScope; 13 use dom::urlhelper::UrlHelper; 14 use dom::window::Window; 15 use dom_struct::dom_struct; 16 use servo_url::{MutableOrigin, ServoUrl}; 17 18 #[dom_struct] 19 pub struct Location { 20 reflector_: Reflector, 21 window: Dom<Window>, 22 } 23 24 impl Location { new_inherited(window: &Window) -> Location25 fn new_inherited(window: &Window) -> Location { 26 Location { 27 reflector_: Reflector::new(), 28 window: Dom::from_ref(window) 29 } 30 } 31 new(window: &Window) -> DomRoot<Location>32 pub fn new(window: &Window) -> DomRoot<Location> { 33 reflect_dom_object(Box::new(Location::new_inherited(window)), 34 window, 35 LocationBinding::Wrap) 36 } 37 get_url(&self) -> ServoUrl38 fn get_url(&self) -> ServoUrl { 39 self.window.get_url() 40 } 41 set_url_component(&self, value: USVString, setter: fn(&mut ServoUrl, USVString))42 fn set_url_component(&self, value: USVString, 43 setter: fn(&mut ServoUrl, USVString)) { 44 let mut url = self.window.get_url(); 45 setter(&mut url, value); 46 self.window.load_url(url, false, false, None); 47 } 48 check_same_origin_domain(&self) -> ErrorResult49 fn check_same_origin_domain(&self) -> ErrorResult { 50 let entry_document = GlobalScope::entry().as_window().Document(); 51 let this_document = self.window.Document(); 52 if entry_document.origin().same_origin_domain(this_document.origin()) { 53 Ok(()) 54 } else { 55 Err(Error::Security) 56 } 57 } 58 59 // https://html.spec.whatwg.org/multipage/#dom-location-reload reload_without_origin_check(&self)60 pub fn reload_without_origin_check(&self) { 61 self.window.load_url(self.get_url(), true, true, None); 62 } 63 64 #[allow(dead_code)] origin(&self) -> &MutableOrigin65 pub fn origin(&self) -> &MutableOrigin { 66 self.window.origin() 67 } 68 } 69 70 impl LocationMethods for Location { 71 // https://html.spec.whatwg.org/multipage/#dom-location-assign Assign(&self, url: USVString) -> ErrorResult72 fn Assign(&self, url: USVString) -> ErrorResult { 73 self.check_same_origin_domain()?; 74 // TODO: per spec, we should use the _API base URL_ specified by the 75 // _entry settings object_. 76 let base_url = self.window.get_url(); 77 if let Ok(url) = base_url.join(&url.0) { 78 self.window.load_url(url, false, false, None); 79 Ok(()) 80 } else { 81 Err(Error::Syntax) 82 } 83 } 84 85 // https://html.spec.whatwg.org/multipage/#dom-location-reload Reload(&self) -> ErrorResult86 fn Reload(&self) -> ErrorResult { 87 self.check_same_origin_domain()?; 88 self.window.load_url(self.get_url(), true, true, None); 89 Ok(()) 90 } 91 92 // https://html.spec.whatwg.org/multipage/#dom-location-replace Replace(&self, url: USVString) -> ErrorResult93 fn Replace(&self, url: USVString) -> ErrorResult { 94 // Note: no call to self.check_same_origin_domain() 95 // TODO: per spec, we should use the _API base URL_ specified by the 96 // _entry settings object_. 97 let base_url = self.window.get_url(); 98 if let Ok(url) = base_url.join(&url.0) { 99 self.window.load_url(url, true, false, None); 100 Ok(()) 101 } else { 102 Err(Error::Syntax) 103 } 104 } 105 106 // https://html.spec.whatwg.org/multipage/#dom-location-hash GetHash(&self) -> Fallible<USVString>107 fn GetHash(&self) -> Fallible<USVString> { 108 self.check_same_origin_domain()?; 109 Ok(UrlHelper::Hash(&self.get_url())) 110 } 111 112 // https://html.spec.whatwg.org/multipage/#dom-location-hash SetHash(&self, mut value: USVString) -> ErrorResult113 fn SetHash(&self, mut value: USVString) -> ErrorResult { 114 if value.0.is_empty() { 115 value = USVString("#".to_owned()); 116 } 117 self.check_same_origin_domain()?; 118 self.set_url_component(value, UrlHelper::SetHash); 119 Ok(()) 120 } 121 122 // https://html.spec.whatwg.org/multipage/#dom-location-host GetHost(&self) -> Fallible<USVString>123 fn GetHost(&self) -> Fallible<USVString> { 124 self.check_same_origin_domain()?; 125 Ok(UrlHelper::Host(&self.get_url())) 126 } 127 128 // https://html.spec.whatwg.org/multipage/#dom-location-host SetHost(&self, value: USVString) -> ErrorResult129 fn SetHost(&self, value: USVString) -> ErrorResult { 130 self.check_same_origin_domain()?; 131 self.set_url_component(value, UrlHelper::SetHost); 132 Ok(()) 133 } 134 135 // https://html.spec.whatwg.org/multipage/#dom-location-origin GetOrigin(&self) -> Fallible<USVString>136 fn GetOrigin(&self) -> Fallible<USVString> { 137 self.check_same_origin_domain()?; 138 Ok(UrlHelper::Origin(&self.get_url())) 139 } 140 141 // https://html.spec.whatwg.org/multipage/#dom-location-hostname GetHostname(&self) -> Fallible<USVString>142 fn GetHostname(&self) -> Fallible<USVString> { 143 self.check_same_origin_domain()?; 144 Ok(UrlHelper::Hostname(&self.get_url())) 145 } 146 147 // https://html.spec.whatwg.org/multipage/#dom-location-hostname SetHostname(&self, value: USVString) -> ErrorResult148 fn SetHostname(&self, value: USVString) -> ErrorResult { 149 self.check_same_origin_domain()?; 150 self.set_url_component(value, UrlHelper::SetHostname); 151 Ok(()) 152 } 153 154 // https://html.spec.whatwg.org/multipage/#dom-location-href GetHref(&self) -> Fallible<USVString>155 fn GetHref(&self) -> Fallible<USVString> { 156 self.check_same_origin_domain()?; 157 Ok(UrlHelper::Href(&self.get_url())) 158 } 159 160 // https://html.spec.whatwg.org/multipage/#dom-location-href SetHref(&self, value: USVString) -> ErrorResult161 fn SetHref(&self, value: USVString) -> ErrorResult { 162 // Note: no call to self.check_same_origin_domain() 163 let url = match self.window.get_url().join(&value.0) { 164 Ok(url) => url, 165 Err(e) => return Err(Error::Type(format!("Couldn't parse URL: {}", e))), 166 }; 167 self.window.load_url(url, false, false, None); 168 Ok(()) 169 } 170 171 // https://html.spec.whatwg.org/multipage/#dom-location-pathname GetPathname(&self) -> Fallible<USVString>172 fn GetPathname(&self) -> Fallible<USVString> { 173 self.check_same_origin_domain()?; 174 Ok(UrlHelper::Pathname(&self.get_url())) 175 } 176 177 // https://html.spec.whatwg.org/multipage/#dom-location-pathname SetPathname(&self, value: USVString) -> ErrorResult178 fn SetPathname(&self, value: USVString) -> ErrorResult { 179 self.check_same_origin_domain()?; 180 self.set_url_component(value, UrlHelper::SetPathname); 181 Ok(()) 182 } 183 184 // https://html.spec.whatwg.org/multipage/#dom-location-port GetPort(&self) -> Fallible<USVString>185 fn GetPort(&self) -> Fallible<USVString> { 186 self.check_same_origin_domain()?; 187 Ok(UrlHelper::Port(&self.get_url())) 188 } 189 190 // https://html.spec.whatwg.org/multipage/#dom-location-port SetPort(&self, value: USVString) -> ErrorResult191 fn SetPort(&self, value: USVString) -> ErrorResult { 192 self.check_same_origin_domain()?; 193 self.set_url_component(value, UrlHelper::SetPort); 194 Ok(()) 195 } 196 197 // https://html.spec.whatwg.org/multipage/#dom-location-protocol GetProtocol(&self) -> Fallible<USVString>198 fn GetProtocol(&self) -> Fallible<USVString> { 199 self.check_same_origin_domain()?; 200 Ok(UrlHelper::Protocol(&self.get_url())) 201 } 202 203 // https://html.spec.whatwg.org/multipage/#dom-location-protocol SetProtocol(&self, value: USVString) -> ErrorResult204 fn SetProtocol(&self, value: USVString) -> ErrorResult { 205 self.check_same_origin_domain()?; 206 self.set_url_component(value, UrlHelper::SetProtocol); 207 Ok(()) 208 } 209 210 // https://html.spec.whatwg.org/multipage/#dom-location-href Stringifier(&self) -> Fallible<DOMString>211 fn Stringifier(&self) -> Fallible<DOMString> { 212 Ok(DOMString::from(self.GetHref()?.0)) 213 } 214 215 // https://html.spec.whatwg.org/multipage/#dom-location-search GetSearch(&self) -> Fallible<USVString>216 fn GetSearch(&self) -> Fallible<USVString> { 217 self.check_same_origin_domain()?; 218 Ok(UrlHelper::Search(&self.get_url())) 219 } 220 221 // https://html.spec.whatwg.org/multipage/#dom-location-search SetSearch(&self, value: USVString) -> ErrorResult222 fn SetSearch(&self, value: USVString) -> ErrorResult { 223 self.check_same_origin_domain()?; 224 self.set_url_component(value, UrlHelper::SetSearch); 225 Ok(()) 226 } 227 } 228