diff options
-rw-r--r-- | components/script/dom/location.rs | 77 | ||||
-rw-r--r-- | components/script/dom/url.rs | 105 | ||||
-rw-r--r-- | components/script/dom/urlhelper.rs | 59 | ||||
-rw-r--r-- | components/script/dom/webidls/URLUtils.webidl | 30 | ||||
-rw-r--r-- | tests/wpt/metadata/url/interfaces.html.ini | 30 |
5 files changed, 220 insertions, 81 deletions
diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs index 22c250bbb55..8b5cf37965e 100644 --- a/components/script/dom/location.rs +++ b/components/script/dom/location.rs @@ -4,6 +4,7 @@ use dom::bindings::codegen::Bindings::LocationBinding; use dom::bindings::codegen::Bindings::LocationBinding::LocationMethods; +use dom::bindings::error::ErrorResult; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, Root}; use dom::bindings::str::USVString; @@ -33,6 +34,18 @@ impl Location { GlobalRef::Window(window), LocationBinding::Wrap) } + + fn get_url(&self) -> Url { + self.window.root().get_url() + } + + fn set_url_component(&self, value: USVString, + setter: fn(&mut Url, USVString)) { + let window = self.window.root(); + let mut url = window.get_url(); + setter(&mut url, value); + window.load_url(url); + } } impl LocationMethods for Location { @@ -52,9 +65,9 @@ impl LocationMethods for Location { UrlHelper::Hash(&self.get_url()) } - // https://url.spec.whatwg.org/#dom-urlutils-href - fn Href(&self) -> USVString { - UrlHelper::Href(&self.get_url()) + // https://url.spec.whatwg.org/#dom-urlutils-hash + fn SetHash(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetHash); } // https://url.spec.whatwg.org/#dom-urlutils-host @@ -62,31 +75,75 @@ impl LocationMethods for Location { UrlHelper::Host(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-host + fn SetHost(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetHost); + } + // https://url.spec.whatwg.org/#dom-urlutils-hostname fn Hostname(&self) -> USVString { UrlHelper::Hostname(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-hostname + fn SetHostname(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetHostname); + } + + // https://url.spec.whatwg.org/#dom-urlutils-href + fn Href(&self) -> USVString { + UrlHelper::Href(&self.get_url()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-href + fn SetHref(&self, value: USVString) -> ErrorResult { + let window = self.window.root(); + if let Ok(url) = UrlParser::new().base_url(&window.get_url()).parse(&value.0) { + window.load_url(url); + }; + Ok(()) + } + // https://url.spec.whatwg.org/#dom-urlutils-password fn Password(&self) -> USVString { UrlHelper::Password(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-password + fn SetPassword(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetPassword); + } + // https://url.spec.whatwg.org/#dom-urlutils-pathname fn Pathname(&self) -> USVString { UrlHelper::Pathname(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-pathname + fn SetPathname(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetPathname); + } + // https://url.spec.whatwg.org/#dom-urlutils-port fn Port(&self) -> USVString { UrlHelper::Port(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-port + fn SetPort(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetPort); + } + // https://url.spec.whatwg.org/#dom-urlutils-protocol fn Protocol(&self) -> USVString { UrlHelper::Protocol(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-protocol + fn SetProtocol(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetProtocol); + } + // https://url.spec.whatwg.org/#URLUtils-stringification-behavior fn Stringifier(&self) -> DOMString { self.Href().0 @@ -97,16 +154,18 @@ impl LocationMethods for Location { UrlHelper::Search(&self.get_url()) } + // https://url.spec.whatwg.org/#dom-urlutils-search + fn SetSearch(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetSearch); + } + // https://url.spec.whatwg.org/#dom-urlutils-username fn Username(&self) -> USVString { UrlHelper::Username(&self.get_url()) } -} - -impl Location { - fn get_url(&self) -> Url { - let window = self.window.root(); - window.r().get_url() + // https://url.spec.whatwg.org/#dom-urlutils-username + fn SetUsername(&self, value: USVString) { + self.set_url_component(value, UrlHelper::SetUsername); } } diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index ec44fe2fdf9..f34428d4bbb 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -3,17 +3,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::codegen::Bindings::URLBinding::{self, URLMethods}; -use dom::bindings::error::{Error, Fallible}; +use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; use dom::bindings::js::Root; use dom::bindings::str::USVString; use dom::bindings::utils::{Reflector, reflect_dom_object}; use dom::urlhelper::UrlHelper; -use url::{Host, Url, UrlParser}; +use url::{Host, ParseResult, Url, UrlParser}; use util::str::DOMString; use std::borrow::ToOwned; +use std::cell::RefCell; // https://url.spec.whatwg.org/#url #[dom_struct] @@ -21,19 +22,23 @@ pub struct URL { reflector_: Reflector, // https://url.spec.whatwg.org/#concept-urlutils-url - url: Url, + url: RefCell<Url>, + + // https://url.spec.whatwg.org/#concept-urlutils-get-the-base + base: Option<Url>, } impl URL { - fn new_inherited(url: Url) -> URL { + fn new_inherited(url: Url, base: Option<Url>) -> URL { URL { reflector_: Reflector::new(), - url: url, + url: RefCell::new(url), + base: base, } } - pub fn new(global: GlobalRef, url: Url) -> Root<URL> { - reflect_dom_object(box URL::new_inherited(url), + pub fn new(global: GlobalRef, url: Url, base: Option<Url>) -> Root<URL> { + reflect_dom_object(box URL::new_inherited(url, base), global, URLBinding::Wrap) } } @@ -59,7 +64,7 @@ impl URL { } }; // Step 3. - let parsed_url = match parser_with_base(parsed_base.as_ref()).parse(&url.0) { + let parsed_url = match parse_with_base(url, parsed_base.as_ref()) { Ok(url) => url, Err(error) => { // Step 4. @@ -67,7 +72,7 @@ impl URL { } }; // Steps 5-8. - Ok(URL::new(global, parsed_url)) + Ok(URL::new(global, parsed_url, parsed_base)) } // https://url.spec.whatwg.org/#dom-url-domaintoasciidomain @@ -87,47 +92,100 @@ impl URL { impl URLMethods for URL { // https://url.spec.whatwg.org/#dom-urlutils-hash fn Hash(&self) -> USVString { - UrlHelper::Hash(&self.url) + UrlHelper::Hash(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-hash + fn SetHash(&self, value: USVString) { + UrlHelper::SetHash(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-host fn Host(&self) -> USVString { - UrlHelper::Host(&self.url) + UrlHelper::Host(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-host + fn SetHost(&self, value: USVString) { + UrlHelper::SetHost(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-hostname fn Hostname(&self) -> USVString { - UrlHelper::Hostname(&self.url) + UrlHelper::Hostname(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-hostname + fn SetHostname(&self, value: USVString) { + UrlHelper::SetHostname(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-href fn Href(&self) -> USVString { - UrlHelper::Href(&self.url) + UrlHelper::Href(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-href + fn SetHref(&self, value: USVString) -> ErrorResult { + match parse_with_base(value, self.base.as_ref()) { + Ok(url) => { + *self.url.borrow_mut() = url; + Ok(()) + }, + Err(error) => { + Err(Error::Type(format!("could not parse URL: {}", error))) + }, + } } // https://url.spec.whatwg.org/#dom-urlutils-password fn Password(&self) -> USVString { - UrlHelper::Password(&self.url) + UrlHelper::Password(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-password + fn SetPassword(&self, value: USVString) { + UrlHelper::SetPassword(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-pathname fn Pathname(&self) -> USVString { - UrlHelper::Pathname(&self.url) + UrlHelper::Pathname(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-pathname + fn SetPathname(&self, value: USVString) { + UrlHelper::SetPathname(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-port fn Port(&self) -> USVString { - UrlHelper::Port(&self.url) + UrlHelper::Port(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-port + fn SetPort(&self, value: USVString) { + UrlHelper::SetPort(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-protocol fn Protocol(&self) -> USVString { - UrlHelper::Protocol(&self.url) + UrlHelper::Protocol(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-protocol + fn SetProtocol(&self, value: USVString) { + UrlHelper::SetProtocol(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#dom-urlutils-search fn Search(&self) -> USVString { - UrlHelper::Search(&self.url) + UrlHelper::Search(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-search + fn SetSearch(&self, value: USVString) { + UrlHelper::SetSearch(&mut self.url.borrow_mut(), value); } // https://url.spec.whatwg.org/#URLUtils-stringification-behavior @@ -137,14 +195,19 @@ impl URLMethods for URL { // https://url.spec.whatwg.org/#dom-urlutils-username fn Username(&self) -> USVString { - UrlHelper::Username(&self.url) + UrlHelper::Username(&self.url.borrow()) + } + + // https://url.spec.whatwg.org/#dom-urlutils-username + fn SetUsername(&self, value: USVString) { + UrlHelper::SetUsername(&mut self.url.borrow_mut(), value); } } -fn parser_with_base(base: Option<&Url>) -> UrlParser { +fn parse_with_base(input: USVString, base: Option<&Url>) -> ParseResult<Url> { let mut parser = UrlParser::new(); if let Some(base) = base { parser.base_url(base); } - parser + parser.parse(&input.0) } diff --git a/components/script/dom/urlhelper.rs b/components/script/dom/urlhelper.rs index 4376a85e390..684d6666e0c 100644 --- a/components/script/dom/urlhelper.rs +++ b/components/script/dom/urlhelper.rs @@ -4,7 +4,9 @@ use dom::bindings::str::USVString; -use url::{Url, SchemeData}; +use url::{Url, UrlParser, SchemeData}; + +use url::urlutils::{UrlUtils, UrlUtilsWrapper}; use std::borrow::ToOwned; use std::fmt::Write; @@ -22,6 +24,12 @@ impl UrlHelper { }) } + // https://url.spec.whatwg.org/#dom-urlutils-hash + pub fn SetHash(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_fragment(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-host pub fn Host(url: &Url) -> USVString { USVString(match url.scheme_data { @@ -36,11 +44,23 @@ impl UrlHelper { }) } + // https://url.spec.whatwg.org/#dom-urlutils-host + pub fn SetHost(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_host(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-hostname pub fn Hostname(url: &Url) -> USVString { USVString(url.serialize_host().unwrap_or_else(|| "".to_owned())) } + // https://url.spec.whatwg.org/#dom-urlutils-hostname + pub fn SetHostname(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_host_and_port(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-href pub fn Href(url: &Url) -> USVString { USVString(url.serialize()) @@ -51,15 +71,26 @@ impl UrlHelper { USVString(url.password().unwrap_or("").to_owned()) } + // https://url.spec.whatwg.org/#dom-urlutils-password + pub fn SetPassword(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_password(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-pathname pub fn Pathname(url: &Url) -> USVString { - // FIXME: Url null check is skipped for now USVString(match url.scheme_data { SchemeData::NonRelative(ref scheme_data) => scheme_data.clone(), SchemeData::Relative(..) => url.serialize_path().unwrap() }) } + // https://url.spec.whatwg.org/#dom-urlutils-pathname + pub fn SetPathname(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_path(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-port pub fn Port(url: &Url) -> USVString { USVString(match url.port() { @@ -68,11 +99,23 @@ impl UrlHelper { }) } + // https://url.spec.whatwg.org/#dom-urlutils-port + pub fn SetPort(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_port(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-protocol pub fn Protocol(url: &Url) -> USVString { USVString(format!("{}:", url.scheme.clone())) } + // https://url.spec.whatwg.org/#dom-urlutils-protocol + pub fn SetProtocol(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_scheme(&value.0); + } + // https://html.spec.whatwg.org/multipage/#same-origin pub fn SameOrigin(urlA: &Url, urlB: &Url) -> bool { if urlA.host() != urlB.host() { @@ -96,8 +139,20 @@ impl UrlHelper { }) } + // https://url.spec.whatwg.org/#dom-urlutils-search + pub fn SetSearch(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_query(&value.0); + } + // https://url.spec.whatwg.org/#dom-urlutils-username pub fn Username(url: &Url) -> USVString { USVString(url.username().unwrap_or("").to_owned()) } + + // https://url.spec.whatwg.org/#dom-urlutils-username + pub fn SetUsername(url: &mut Url, value: USVString) { + let mut wrapper = UrlUtilsWrapper { url: url, parser: &UrlParser::new() }; + let _ = wrapper.set_username(&value.0); + } } diff --git a/components/script/dom/webidls/URLUtils.webidl b/components/script/dom/webidls/URLUtils.webidl index 86e5140311b..1b8965f3d37 100644 --- a/components/script/dom/webidls/URLUtils.webidl +++ b/components/script/dom/webidls/URLUtils.webidl @@ -7,27 +7,19 @@ [NoInterfaceObject] interface URLUtils { //stringifier attribute USVString href; - readonly attribute USVString href; + [SetterThrows] + attribute USVString href; //readonly attribute USVString origin; - // attribute USVString protocol; - readonly attribute USVString protocol; - // attribute USVString username; - readonly attribute USVString username; - // attribute USVString password; - readonly attribute USVString password; - // attribute USVString host; - readonly attribute USVString host; - // attribute USVString hostname; - readonly attribute USVString hostname; - // attribute USVString port; - readonly attribute USVString port; - // attribute USVString pathname; - readonly attribute USVString pathname; - // attribute USVString search; - readonly attribute USVString search; + attribute USVString protocol; + attribute USVString username; + attribute USVString password; + attribute USVString host; + attribute USVString hostname; + attribute USVString port; + attribute USVString pathname; + attribute USVString search; // attribute URLSearchParams searchParams; - // attribute USVString hash; - readonly attribute USVString hash; + attribute USVString hash; // This is only doing as well as gecko right now, bug 824857 is on file for // adding attribute stringifier support. diff --git a/tests/wpt/metadata/url/interfaces.html.ini b/tests/wpt/metadata/url/interfaces.html.ini index f1a85fdfc35..17a665ab572 100644 --- a/tests/wpt/metadata/url/interfaces.html.ini +++ b/tests/wpt/metadata/url/interfaces.html.ini @@ -3,42 +3,12 @@ [URL interface: operation domainToUnicode(ScalarValueString)] expected: FAIL - [URL interface: attribute href] - expected: FAIL - [URL interface: attribute origin] expected: FAIL - [URL interface: attribute protocol] - expected: FAIL - - [URL interface: attribute username] - expected: FAIL - - [URL interface: attribute password] - expected: FAIL - - [URL interface: attribute host] - expected: FAIL - - [URL interface: attribute hostname] - expected: FAIL - - [URL interface: attribute port] - expected: FAIL - - [URL interface: attribute pathname] - expected: FAIL - - [URL interface: attribute search] - expected: FAIL - [URL interface: attribute searchParams] expected: FAIL - [URL interface: attribute hash] - expected: FAIL - [URL interface: new URL("http://foo") must inherit property "origin" with the proper type (3)] expected: FAIL |