aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-05-27 05:21:05 -0500
committerbors-servo <metajack+bors@gmail.com>2015-05-27 05:21:05 -0500
commitd87af8ac52b16a3763420fb7ad8fb45af785a23b (patch)
treeffbb9a1f719c29197d2387583c5e01c039f1cefd
parentdf2f8d0636922a7e89895fa61fdba30099cec9ea (diff)
parent6802bafc399011726c51ca55fdde6d34f98430f1 (diff)
downloadservo-d87af8ac52b16a3763420fb7ad8fb45af785a23b.tar.gz
servo-d87af8ac52b16a3763420fb7ad8fb45af785a23b.zip
Auto merge of #6192 - nox:cleanup-urlsearchparams, r=Manishearth
It now uses rust-url for its serializer. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6192) <!-- Reviewable:end -->
-rw-r--r--components/script/Cargo.toml5
-rw-r--r--components/script/dom/urlsearchparams.rs167
-rw-r--r--components/script/dom/xmlhttprequest.rs13
-rw-r--r--components/servo/Cargo.lock1
4 files changed, 84 insertions, 102 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 54f83eb9cfc..1150c638607 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -69,9 +69,12 @@ git = "https://github.com/servo/string-cache"
[dependencies.string_cache_plugin]
git = "https://github.com/servo/string-cache"
+[dependencies.url]
+version = "0.2.33"
+features = ["query_encoding"]
+
[dependencies]
encoding = "0.2"
-url = "0.2.16"
time = "0.1.12"
bitflags = "*"
rustc-serialize = "*"
diff --git a/components/script/dom/urlsearchparams.rs b/components/script/dom/urlsearchparams.rs
index 91c25794716..f4b525418f8 100644
--- a/components/script/dom/urlsearchparams.rs
+++ b/components/script/dom/urlsearchparams.rs
@@ -7,31 +7,28 @@ use dom::bindings::codegen::Bindings::URLSearchParamsBinding;
use dom::bindings::codegen::Bindings::URLSearchParamsBinding::URLSearchParamsMethods;
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams;
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eURLSearchParams, eString};
-use dom::bindings::error::{Fallible};
+use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Rootable, Temporary};
use dom::bindings::utils::{Reflector, reflect_dom_object};
+use encoding::types::EncodingRef;
+use url::form_urlencoded::{parse, serialize_with_encoding};
use util::str::DOMString;
-use encoding::all::UTF_8;
-use encoding::types::{EncodingRef, EncoderTrap};
-
-use std::collections::HashMap;
-use std::collections::hash_map::Entry::{Occupied, Vacant};
-
// https://url.spec.whatwg.org/#interface-urlsearchparams
#[dom_struct]
pub struct URLSearchParams {
reflector_: Reflector,
- data: DOMRefCell<HashMap<DOMString, Vec<DOMString>>>,
+ // https://url.spec.whatwg.org/#concept-urlsearchparams-list
+ list: DOMRefCell<Vec<(DOMString, DOMString)>>,
}
impl URLSearchParams {
fn new_inherited() -> URLSearchParams {
URLSearchParams {
reflector_: Reflector::new(),
- data: DOMRefCell::new(HashMap::new()),
+ list: DOMRefCell::new(vec![]),
}
}
@@ -43,137 +40,113 @@ impl URLSearchParams {
// https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams
pub fn Constructor(global: GlobalRef, init: Option<StringOrURLSearchParams>) ->
Fallible<Temporary<URLSearchParams>> {
- let usp = URLSearchParams::new(global).root();
+ // Step 1.
+ let query = URLSearchParams::new(global).root();
match init {
- Some(eString(_s)) => {
- // XXXManishearth we need to parse the input here
- // https://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(eString(init)) => {
+ // Step 2.
+ let query = query.r();
+ *query.list.borrow_mut() = parse(init.as_bytes());
},
- Some(eURLSearchParams(u)) => {
- let u = u.root();
- let usp = usp.r();
- let mut map = usp.data.borrow_mut();
+ Some(eURLSearchParams(init)) => {
+ // Step 3.
// FIXME(https://github.com/rust-lang/rust/issues/23338)
- let r = u.r();
- let data = r.data.borrow();
- *map = data.clone();
+ let query = query.r();
+ let init = init.root();
+ let init = init.r();
+ *query.list.borrow_mut() = init.list.borrow().clone();
},
None => {}
}
- Ok(Temporary::from_rooted(usp.r()))
+ // Step 4.
+ Ok(Temporary::from_rooted(query.r()))
}
}
impl<'a> URLSearchParamsMethods for JSRef<'a, URLSearchParams> {
// https://url.spec.whatwg.org/#dom-urlsearchparams-append
fn Append(self, name: DOMString, value: DOMString) {
- let mut data = self.data.borrow_mut();
-
- match data.entry(name) {
- Occupied(entry) => entry.into_mut().push(value),
- Vacant(entry) => {
- entry.insert(vec!(value));
- }
- }
-
+ // Step 1.
+ self.list.borrow_mut().push((name, value));
+ // Step 2.
self.update_steps();
}
// https://url.spec.whatwg.org/#dom-urlsearchparams-delete
fn Delete(self, name: DOMString) {
- self.data.borrow_mut().remove(&name);
+ // Step 1.
+ self.list.borrow_mut().retain(|&(ref k, _)| k != &name);
+ // Step 2.
self.update_steps();
}
// https://url.spec.whatwg.org/#dom-urlsearchparams-get
fn Get(self, name: DOMString) -> Option<DOMString> {
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let data = self.data.borrow();
- data.get(&name).map(|v| v[0].clone())
+ let list = self.list.borrow();
+ list.iter().filter_map(|&(ref k, ref v)| {
+ if k == &name {
+ Some(v.clone())
+ } else {
+ None
+ }
+ }).next()
}
// https://url.spec.whatwg.org/#dom-urlsearchparams-has
fn Has(self, name: DOMString) -> bool {
- // FIXME(https://github.com/rust-lang/rust/issues/23338)
- let data = self.data.borrow();
- data.contains_key(&name)
+ let list = self.list.borrow();
+ list.iter().find(|&&(ref k, _)| k == &name).is_some()
}
// https://url.spec.whatwg.org/#dom-urlsearchparams-set
fn Set(self, name: DOMString, value: DOMString) {
- self.data.borrow_mut().insert(name, vec!(value));
+ let mut list = self.list.borrow_mut();
+ let mut index = None;
+ let mut i = 0;
+ list.retain(|&(ref k, _)| {
+ if index.is_none() {
+ if k == &name {
+ index = Some(i);
+ } else {
+ i += 1;
+ }
+ true
+ } else {
+ k != &name
+ }
+ });
+ match index {
+ Some(index) => list[index].1 = value,
+ None => list.push((name, value)),
+ };
self.update_steps();
}
// https://url.spec.whatwg.org/#stringification-behavior
fn Stringifier(self) -> DOMString {
- DOMString::from_utf8(self.serialize(None)).unwrap()
+ self.serialize(None)
}
}
pub trait URLSearchParamsHelpers {
- fn serialize(&self, encoding: Option<EncodingRef>) -> Vec<u8>;
- fn update_steps(&self);
+ fn serialize(self, encoding: Option<EncodingRef>) -> DOMString;
}
-impl URLSearchParamsHelpers for URLSearchParams {
- fn serialize(&self, encoding: Option<EncodingRef>) -> Vec<u8> {
- // https://url.spec.whatwg.org/#concept-urlencoded-serializer
- fn serialize_string(value: &str, encoding: EncodingRef) -> Vec<u8> {
- // https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer
-
- // XXXManishearth should this be a strict encoding? Can unwrap()ing the result fail?
- let value = encoding.encode(value, EncoderTrap::Replace).unwrap();
-
- // Step 1.
- let mut buf = vec!();
-
- // Step 2.
- for i in &value {
- let append = match *i {
- // Convert spaces:
- // ' ' => '+'
- 0x20 => vec!(0x2B),
-
- // Retain the following characters:
- // '*', '-', '.', '0'...'9', 'A'...'Z', '_', 'a'...'z'
- 0x2A | 0x2D | 0x2E | 0x30...0x39 |
- 0x41...0x5A | 0x5F | 0x61...0x7A => vec!(*i),
-
- // Encode everything else using 'percented-encoded bytes'
- // https://url.spec.whatwg.org/#percent-encode
- a => format!("%{:02X}", a).into_bytes(),
- };
- buf.push_all(&append);
- }
-
- // Step 3.
- buf
- }
- let encoding = encoding.unwrap_or(UTF_8 as EncodingRef);
- let mut buf = vec!();
- let mut first_pair = true;
- for (k, v) in self.data.borrow().iter() {
- let name = serialize_string(k, encoding);
- for val in v {
- let value = serialize_string(val, encoding);
- if first_pair {
- first_pair = false;
- } else {
- buf.push(0x26); // &
- }
- buf.push_all(&name);
- buf.push(0x3D); // =
- buf.push_all(&value)
- }
- }
- buf
+impl<'a> URLSearchParamsHelpers for JSRef<'a, URLSearchParams> {
+ // https://url.spec.whatwg.org/#concept-urlencoded-serializer
+ fn serialize(self, encoding: Option<EncodingRef>) -> DOMString {
+ let list = self.list.borrow();
+ serialize_with_encoding(list.iter(), encoding)
}
+}
+
+trait PrivateURLSearchParamsHelpers {
+ fn update_steps(self);
+}
- fn update_steps(&self) {
+impl<'a> PrivateURLSearchParamsHelpers for JSRef<'a, URLSearchParams> {
+ // https://url.spec.whatwg.org/#concept-uq-update
+ fn update_steps(self) {
// XXXManishearth Implement this when the URL interface is implemented
- // https://url.spec.whatwg.org/#concept-uq-update
}
}
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 99d412ee8b7..5044feae3b7 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -1129,12 +1129,17 @@ trait Extractable {
fn extract(&self) -> Vec<u8>;
}
impl Extractable for SendParam {
+ // https://fetch.spec.whatwg.org/#concept-bodyinit-extract
fn extract(&self) -> Vec<u8> {
- // https://fetch.spec.whatwg.org/#concept-fetchbodyinit-extract
- let encoding = UTF_8 as EncodingRef;
match *self {
- eString(ref s) => encoding.encode(s, EncoderTrap::Replace).unwrap(),
- eURLSearchParams(ref usp) => usp.root().r().serialize(None) // Default encoding is UTF8
+ eString(ref s) => {
+ let encoding = UTF_8 as EncodingRef;
+ encoding.encode(s, EncoderTrap::Replace).unwrap()
+ },
+ eURLSearchParams(ref usp) => {
+ // Default encoding is UTF-8.
+ usp.root().r().serialize(None).as_bytes().to_owned()
+ },
}
}
}
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 598c279c7e9..37b40296542 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -1219,6 +1219,7 @@ name = "url"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
+ "encoding 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]