diff options
author | Josh Matthews <josh@joshmatthews.net> | 2014-07-02 16:51:38 -0400 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2014-07-02 16:51:38 -0400 |
commit | d09815a10a7841afe8453577104e9ab5b3c841b0 (patch) | |
tree | 2a3a3e27cdac03c8de5a3437ff10954c6f68e6f3 /src | |
parent | a313bdb346fa7d40a7527138c998dc105e9215ee (diff) | |
parent | 8790a0f6f6f19a3074ce9ccfd2f05ee253143062 (diff) | |
download | servo-d09815a10a7841afe8453577104e9ab5b3c841b0.tar.gz servo-d09815a10a7841afe8453577104e9ab5b3c841b0.zip |
Merge pull request #2735 from Manishearth/urlsearchparams
Add URLSearchParams interface with serialization support
Diffstat (limited to 'src')
-rw-r--r-- | src/components/script/dom/bindings/codegen/Bindings.conf | 1 | ||||
-rw-r--r-- | src/components/script/dom/urlsearchparams.rs | 154 | ||||
-rw-r--r-- | src/components/script/dom/webidls/URLSearchParams.webidl | 19 | ||||
-rw-r--r-- | src/components/script/script.rs | 3 |
4 files changed, 176 insertions, 1 deletions
diff --git a/src/components/script/dom/bindings/codegen/Bindings.conf b/src/components/script/dom/bindings/codegen/Bindings.conf index 3d21aa4f085..326dfcd95b9 100644 --- a/src/components/script/dom/bindings/codegen/Bindings.conf +++ b/src/components/script/dom/bindings/codegen/Bindings.conf @@ -122,6 +122,7 @@ DOMInterfaces = { 'ProgressEvent': {}, 'Text': {}, 'UIEvent': {}, +'URLSearchParams': {}, 'ValidityState': {}, 'Window': { 'createGlobal': True, diff --git a/src/components/script/dom/urlsearchparams.rs b/src/components/script/dom/urlsearchparams.rs new file mode 100644 index 00000000000..0455cc673a7 --- /dev/null +++ b/src/components/script/dom/urlsearchparams.rs @@ -0,0 +1,154 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use std::collections::hashmap::HashMap; +use dom::bindings::codegen::Bindings::URLSearchParamsBinding; +use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{StringOrURLSearchParams, eURLSearchParams, eString}; +use dom::bindings::error::{Fallible}; +use dom::bindings::js::{JSRef, Temporary}; +use dom::bindings::trace::Traceable; +use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; +use dom::window::Window; +use encoding::all::UTF_8; +use encoding::types::{Encoding, EncodeReplace}; +use servo_util::str::DOMString; +use std::cell::RefCell; +use std::num::ToStrRadix; +use std::ascii::OwnedStrAsciiExt; + +#[deriving(Encodable)] +pub struct URLSearchParams{ + pub data: Traceable<RefCell<HashMap<DOMString, Vec<DOMString>>>>, + pub reflector_: Reflector, +} + +impl URLSearchParams { + pub fn new_inherited() -> URLSearchParams { + URLSearchParams { + data: Traceable::new(RefCell::new(HashMap::new())), + reflector_: Reflector::new(), + } + } + + pub fn new(window: &JSRef<Window>) -> Temporary<URLSearchParams> { + reflect_dom_object(box URLSearchParams::new_inherited(), window, URLSearchParamsBinding::Wrap) + } + + pub fn Constructor(window: &JSRef<Window>, init: Option<StringOrURLSearchParams>) -> Fallible<Temporary<URLSearchParams>> { + let usp = URLSearchParams::new(window).root(); + match init { + Some(eString(_s)) => { + // XXXManishearth we need to parse the input here + // http://url.spec.whatwg.org/#concept-urlencoded-parser + // We can use rust-url's implementation here: + // https://github.com/SimonSapin/rust-url/blob/master/form_urlencoded.rs#L29 + }, + Some(eURLSearchParams(u)) => { + let u = u.root(); + let mut map = usp.deref().data.deref().borrow_mut(); + *map = u.data.deref().borrow().clone(); + }, + None => {} + } + Ok(Temporary::from_rooted(&*usp)) + } +} + +pub trait URLSearchParamsMethods { + fn Append(&self, name: DOMString, value: DOMString); + fn Delete(&self, name: DOMString); + fn Get(&self, name: DOMString) -> Option<DOMString>; + fn Has(&self, name: DOMString) -> bool; + fn Set(&self, name: DOMString, value: DOMString); +} + +impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> { + fn Append(&self, name: DOMString, value: DOMString) { + self.data.deref().borrow_mut().insert_or_update_with(name, vec!(value.clone()), + |_k, v| v.push(value.clone())); + self.update_steps(); + } + + fn Delete(&self, name: DOMString) { + self.data.deref().borrow_mut().remove(&name); + self.update_steps(); + } + + fn Get(&self, name: DOMString) -> Option<DOMString> { + self.data.deref().borrow().find_equiv(&name).map(|v| v.get(0).clone()) + } + + fn Has(&self, name: DOMString) -> bool { + self.data.deref().borrow().contains_key_equiv(&name) + } + + fn Set(&self, name: DOMString, value: DOMString) { + self.data.deref().borrow_mut().insert(name, vec!(value)); + self.update_steps(); + } +} + +impl Reflectable for URLSearchParams { + fn reflector<'a>(&'a self) -> &'a Reflector { + &self.reflector_ + } +} + +pub trait URLSearchParamsHelpers { + fn serialize(&self, encoding: Option<&'static Encoding>) -> Vec<u8>; + fn update_steps(&self); +} + +impl URLSearchParamsHelpers for URLSearchParams { + fn serialize(&self, encoding: Option<&'static Encoding>) -> Vec<u8> { + // http://url.spec.whatwg.org/#concept-urlencoded-serializer + fn serialize_string(value: &DOMString, encoding: &'static Encoding) -> Vec<u8> { + // http://url.spec.whatwg.org/#concept-urlencoded-byte-serializer + + let value = value.as_slice(); + // XXXManishearth should this be a strict encoding? Can unwrap()ing the result fail? + let value = encoding.encode(value, EncodeReplace).unwrap(); + let mut buf = vec!(); + for i in value.iter() { + let append = match *i { + 0x20 => vec!(0x2B), + 0x2A | 0x2D | 0x2E | + 0x30 .. 0x39 | 0x41 .. 0x5A | + 0x5F | 0x61..0x7A => vec!(*i), + a => { + // http://url.spec.whatwg.org/#percent-encode + let mut encoded = vec!(0x25); // % + encoded.push_all(a.to_str_radix(16).into_ascii_upper().as_bytes()); + encoded + } + }; + buf.push_all(append.as_slice()); + } + buf + } + let encoding = encoding.unwrap_or(UTF_8 as &'static Encoding); + let mut buf = vec!(); + let mut first_pair = true; + for (k, v) in self.data.deref().borrow().iter() { + let name = serialize_string(k, encoding); + for val in v.iter() { + let value = serialize_string(val, encoding); + if first_pair { + first_pair = false; + } else { + buf.push(0x26); // & + } + buf.push_all(name.as_slice()); + buf.push(0x3D); // = + buf.push_all(value.as_slice()) + } + } + buf + } + + fn update_steps(&self) { + // XXXManishearth Implement this when the URL interface is implemented + // http://url.spec.whatwg.org/#concept-uq-update + } +}
\ No newline at end of file diff --git a/src/components/script/dom/webidls/URLSearchParams.webidl b/src/components/script/dom/webidls/URLSearchParams.webidl new file mode 100644 index 00000000000..adde76b79d7 --- /dev/null +++ b/src/components/script/dom/webidls/URLSearchParams.webidl @@ -0,0 +1,19 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://url.spec.whatwg.org/#interface-urlsearchparams + */ + +[Constructor(optional (DOMString or URLSearchParams) init)] +interface URLSearchParams { + void append(DOMString name, DOMString value); + void delete(DOMString name); + DOMString? get(DOMString name); + // sequence<DOMString> getAll(DOMString name); + boolean has(DOMString name); + void set(DOMString name, DOMString value); + stringifier; +};
\ No newline at end of file diff --git a/src/components/script/script.rs b/src/components/script/script.rs index f3b84dec1af..5ebbc4cbb92 100644 --- a/src/components/script/script.rs +++ b/src/components/script/script.rs @@ -166,8 +166,9 @@ pub mod dom { pub mod performance; pub mod performancetiming; pub mod progressevent; - pub mod uievent; pub mod text; + pub mod uievent; + pub mod urlsearchparams; pub mod validitystate; pub mod virtualmethods; pub mod window; |