From 7001583047e7284de8387472bcfe93d5381471ae Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 20 Dec 2015 00:42:59 -0800 Subject: [PATCH] Refactor FormData code to match updated spec Use Atoms instead of Strings as keys --- components/script/dom/formdata.rs | 94 +++++++++------ components/script/dom/webidls/FormData.webidl | 23 ++-- tests/wpt/metadata/MANIFEST.json | 24 ++++ .../XMLHttpRequest/FormData-append.html.ini | 2 + .../XMLHttpRequest/formdata-delete.htm.ini | 7 ++ .../XMLHttpRequest/formdata-get.htm.ini | 6 + .../XMLHttpRequest/formdata-has.htm.ini | 5 + .../XMLHttpRequest/formdata-set.htm.ini | 7 ++ .../XMLHttpRequest/interfaces.html.ini | 15 --- .../XMLHttpRequest/FormData-append.html | 114 ++++++++++++++---- .../XMLHttpRequest/formdata-delete.htm | 65 ++++++++++ .../XMLHttpRequest/formdata-get.htm | 60 +++++++++ .../XMLHttpRequest/formdata-has.htm | 42 +++++++ .../XMLHttpRequest/formdata-set.htm | 94 +++++++++++++++ 14 files changed, 469 insertions(+), 89 deletions(-) create mode 100644 tests/wpt/metadata/XMLHttpRequest/formdata-delete.htm.ini create mode 100644 tests/wpt/metadata/XMLHttpRequest/formdata-get.htm.ini create mode 100644 tests/wpt/metadata/XMLHttpRequest/formdata-has.htm.ini create mode 100644 tests/wpt/metadata/XMLHttpRequest/formdata-set.htm.ini create mode 100644 tests/wpt/web-platform-tests/XMLHttpRequest/formdata-delete.htm create mode 100644 tests/wpt/web-platform-tests/XMLHttpRequest/formdata-get.htm create mode 100644 tests/wpt/web-platform-tests/XMLHttpRequest/formdata-has.htm create mode 100644 tests/wpt/web-platform-tests/XMLHttpRequest/formdata-set.htm diff --git a/components/script/dom/formdata.rs b/components/script/dom/formdata.rs index 01fc4b140c6..f0cc080489c 100644 --- a/components/script/dom/formdata.rs +++ b/components/script/dom/formdata.rs @@ -5,32 +5,33 @@ use dom::bindings::cell::DOMRefCell; use dom::bindings::codegen::Bindings::FormDataBinding; use dom::bindings::codegen::Bindings::FormDataBinding::FormDataMethods; -use dom::bindings::codegen::UnionTypes::FileOrString; -use dom::bindings::codegen::UnionTypes::FileOrString::{eFile, eString}; +use dom::bindings::codegen::UnionTypes::BlobOrUSVString::{self, eBlob, eUSVString}; use dom::bindings::error::{Fallible}; use dom::bindings::global::{GlobalField, GlobalRef}; use dom::bindings::inheritance::Castable; use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; +use dom::bindings::str::USVString; use dom::blob::Blob; use dom::file::File; use dom::htmlformelement::HTMLFormElement; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; +use string_cache::Atom; use util::str::DOMString; #[derive(JSTraceable, Clone)] #[must_root] #[derive(HeapSizeOf)] pub enum FormDatum { - StringData(DOMString), - FileData(JS) + StringData(String), + BlobData(JS) } #[dom_struct] pub struct FormData { reflector_: Reflector, - data: DOMRefCell>>, + data: DOMRefCell>>, global: GlobalField, form: Option> } @@ -51,72 +52,87 @@ impl FormData { } pub fn Constructor(global: GlobalRef, form: Option<&HTMLFormElement>) -> Fallible> { + // TODO: Construct form data set for form if it is supplied Ok(FormData::new(form, global)) } } impl FormDataMethods for FormData { + // https://xhr.spec.whatwg.org/#dom-formdata-append + fn Append(&self, name: USVString, value: USVString) { + let mut data = self.data.borrow_mut(); + match data.entry(Atom::from(&*name.0)) { + Occupied(entry) => entry.into_mut().push(FormDatum::StringData(value.0)), + Vacant (entry) => { entry.insert(vec!(FormDatum::StringData(value.0))); } + } + } + #[allow(unrooted_must_root)] // https://xhr.spec.whatwg.org/#dom-formdata-append - fn Append(&self, name: DOMString, value: &Blob, filename: Option) { - let file = FormDatum::FileData(JS::from_rooted(&self.get_file_from_blob(value, filename))); + fn Append_(&self, name: USVString, value: &Blob, filename: Option) { + let blob = FormDatum::BlobData(JS::from_rooted(&self.get_file_or_blob(value, filename))); let mut data = self.data.borrow_mut(); - match data.entry(name) { - Occupied(entry) => entry.into_mut().push(file), + match data.entry(Atom::from(&*name.0)) { + Occupied(entry) => entry.into_mut().push(blob), Vacant(entry) => { - entry.insert(vec!(file)); + entry.insert(vec!(blob)); } } } - // https://xhr.spec.whatwg.org/#dom-formdata-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(FormDatum::StringData(value)), - Vacant (entry) => { entry.insert(vec!(FormDatum::StringData(value))); }, - } - } - // https://xhr.spec.whatwg.org/#dom-formdata-delete - fn Delete(&self, name: DOMString) { - self.data.borrow_mut().remove(&name); + fn Delete(&self, name: USVString) { + self.data.borrow_mut().remove(&Atom::from(&*name.0)); } // https://xhr.spec.whatwg.org/#dom-formdata-get - fn Get(&self, name: DOMString) -> Option { + fn Get(&self, name: USVString) -> Option { self.data.borrow() - .get(&name) + .get(&Atom::from(&*name.0)) .map(|entry| match entry[0] { - FormDatum::StringData(ref s) => eString(s.clone()), - FormDatum::FileData(ref f) => eFile(Root::from_ref(&*f)), + FormDatum::StringData(ref s) => eUSVString(USVString(s.clone())), + FormDatum::BlobData(ref b) => eBlob(Root::from_ref(&*b)), }) } - // https://xhr.spec.whatwg.org/#dom-formdata-has - fn Has(&self, name: DOMString) -> bool { - self.data.borrow().contains_key(&name) + // https://xhr.spec.whatwg.org/#dom-formdata-getall + fn GetAll(&self, name: USVString) -> Vec { + self.data.borrow() + .get(&Atom::from(&*name.0)) + .map_or(vec![], |data| + data.iter().map(|item| match *item { + FormDatum::StringData(ref s) => eUSVString(USVString(s.clone())), + FormDatum::BlobData(ref b) => eBlob(Root::from_ref(&*b)), + }).collect() + ) } - // https://xhr.spec.whatwg.org/#dom-formdata-set - fn Set_(&self, name: DOMString, value: DOMString) { - self.data.borrow_mut().insert(name, vec!(FormDatum::StringData(value))); + // https://xhr.spec.whatwg.org/#dom-formdata-has + fn Has(&self, name: USVString) -> bool { + self.data.borrow().contains_key(&Atom::from(&*name.0)) } #[allow(unrooted_must_root)] // https://xhr.spec.whatwg.org/#dom-formdata-set - fn Set(&self, name: DOMString, value: &Blob, filename: Option) { - let file = FormDatum::FileData(JS::from_rooted(&self.get_file_from_blob(value, filename))); - self.data.borrow_mut().insert(name, vec!(file)); + fn Set(&self, name: USVString, value: BlobOrUSVString) { + let val = match value { + eUSVString(s) => FormDatum::StringData(s.0), + eBlob(b) => FormDatum::BlobData(JS::from_rooted(&b)) + }; + self.data.borrow_mut().insert(Atom::from(&*name.0), vec!(val)); } } impl FormData { - fn get_file_from_blob(&self, value: &Blob, filename: Option) -> Root { - let global = self.global.root(); - let f = value.downcast::(); - let name = filename.unwrap_or(f.map(|inner| inner.name().clone()).unwrap_or(DOMString::from("blob"))); - File::new(global.r(), value, name) + fn get_file_or_blob(&self, value: &Blob, filename: Option) -> Root { + match filename { + Some(fname) => { + let global = self.global.root(); + let name = DOMString::from(fname.0); + Root::upcast(File::new(global.r(), value, name)) + } + None => Root::from_ref(value) + } } } diff --git a/components/script/dom/webidls/FormData.webidl b/components/script/dom/webidls/FormData.webidl index 96eccba673b..da8a0ca8dde 100644 --- a/components/script/dom/webidls/FormData.webidl +++ b/components/script/dom/webidls/FormData.webidl @@ -4,19 +4,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * The origin of this IDL file is - * https://xhr.spec.whatwg.org + * https://xhr.spec.whatwg.org/#interface-formdata */ -typedef (File or DOMString) FormDataEntryValue; +typedef (Blob or USVString) FormDataEntryValue; -[Constructor(optional HTMLFormElement form)] +[Constructor(optional HTMLFormElement form), + /*Exposed=(Window,Worker)*/] interface FormData { - void append(DOMString name, Blob value, optional DOMString filename); - void append(DOMString name, DOMString value); - void delete(DOMString name); - FormDataEntryValue? get(DOMString name); - // sequence getAll(DOMString name); - boolean has(DOMString name); - void set(DOMString name, Blob value, optional DOMString filename); - void set(DOMString name, DOMString value); + void append(USVString name, USVString value); + void append(USVString name, Blob value, optional USVString filename); + void delete(USVString name); + FormDataEntryValue? get(USVString name); + sequence getAll(USVString name); + boolean has(USVString name); + void set(USVString name, FormDataEntryValue value); + // iterable; }; diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 6a3a1ba2a5a..1b80ded0e62 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -30174,6 +30174,30 @@ "deleted": [], "items": { "testharness": { + "XMLHttpRequest/formdata-delete.htm": [ + { + "path": "XMLHttpRequest/formdata-delete.htm", + "url": "/XMLHttpRequest/formdata-delete.htm" + } + ], + "XMLHttpRequest/formdata-get.htm": [ + { + "path": "XMLHttpRequest/formdata-get.htm", + "url": "/XMLHttpRequest/formdata-get.htm" + } + ], + "XMLHttpRequest/formdata-has.htm": [ + { + "path": "XMLHttpRequest/formdata-has.htm", + "url": "/XMLHttpRequest/formdata-has.htm" + } + ], + "XMLHttpRequest/formdata-set.htm": [ + { + "path": "XMLHttpRequest/formdata-set.htm", + "url": "/XMLHttpRequest/formdata-set.htm" + } + ], "html/semantics/forms/the-button-element/button-activate.html": [ { "path": "html/semantics/forms/the-button-element/button-activate.html", diff --git a/tests/wpt/metadata/XMLHttpRequest/FormData-append.html.ini b/tests/wpt/metadata/XMLHttpRequest/FormData-append.html.ini index 981c886024d..4e18f0491b6 100644 --- a/tests/wpt/metadata/XMLHttpRequest/FormData-append.html.ini +++ b/tests/wpt/metadata/XMLHttpRequest/FormData-append.html.ini @@ -2,4 +2,6 @@ type: testharness [Passing a String object to FormData.append should work.] expected: FAIL + [testFormDataAppendEmptyBlob] + expected: FAIL diff --git a/tests/wpt/metadata/XMLHttpRequest/formdata-delete.htm.ini b/tests/wpt/metadata/XMLHttpRequest/formdata-delete.htm.ini new file mode 100644 index 00000000000..2ddeca711b5 --- /dev/null +++ b/tests/wpt/metadata/XMLHttpRequest/formdata-delete.htm.ini @@ -0,0 +1,7 @@ +[formdata-delete.htm] + type:testharness + [testFormDataDeleteFromFormNonExistentKey] + expected: FAIL + [testFormDataDeleteFromFormOtherKey] + expected: FAIL + diff --git a/tests/wpt/metadata/XMLHttpRequest/formdata-get.htm.ini b/tests/wpt/metadata/XMLHttpRequest/formdata-get.htm.ini new file mode 100644 index 00000000000..3b83c7c629a --- /dev/null +++ b/tests/wpt/metadata/XMLHttpRequest/formdata-get.htm.ini @@ -0,0 +1,6 @@ +[formdata-get.htm] + type: testharness + [testFormDataGetFromForm] + expected: FAIL + [testFormDataGetAllFromForm] + expected: FAIL diff --git a/tests/wpt/metadata/XMLHttpRequest/formdata-has.htm.ini b/tests/wpt/metadata/XMLHttpRequest/formdata-has.htm.ini new file mode 100644 index 00000000000..65385fa3df7 --- /dev/null +++ b/tests/wpt/metadata/XMLHttpRequest/formdata-has.htm.ini @@ -0,0 +1,5 @@ +[formdata-has.htm] + type: testharness + [testFormDataHasFromForm] + expected: FAIL + diff --git a/tests/wpt/metadata/XMLHttpRequest/formdata-set.htm.ini b/tests/wpt/metadata/XMLHttpRequest/formdata-set.htm.ini new file mode 100644 index 00000000000..693d695481b --- /dev/null +++ b/tests/wpt/metadata/XMLHttpRequest/formdata-set.htm.ini @@ -0,0 +1,7 @@ +[formdata-set.htm] + type: testharness + [Passing a String object to FormData.set should work] + expected: FAIL + [testFormDataSetEmptyBlob] + expected: FAIL + diff --git a/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini b/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini index fcfceffb01d..48adbf303ae 100644 --- a/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini +++ b/tests/wpt/metadata/XMLHttpRequest/interfaces.html.ini @@ -1,20 +1,5 @@ [interfaces.html] type: testharness - [FormData interface: new FormData() must inherit property "getAll" with the proper type (4)] - expected: FAIL - - [FormData interface: new FormData(form) must inherit property "getAll" with the proper type (4)] - expected: FAIL - - [FormData interface: operation getAll(USVString)] - expected: FAIL - - [FormData interface: calling getAll(USVString) on new FormData() with too few arguments must throw TypeError] - expected: FAIL - - [FormData interface: calling getAll(USVString) on new FormData(form) with too few arguments must throw TypeError] - expected: FAIL - [ProgressEvent interface: existence and properties of interface object] expected: FAIL diff --git a/tests/wpt/web-platform-tests/XMLHttpRequest/FormData-append.html b/tests/wpt/web-platform-tests/XMLHttpRequest/FormData-append.html index f20009e2a81..0b81acc0825 100644 --- a/tests/wpt/web-platform-tests/XMLHttpRequest/FormData-append.html +++ b/tests/wpt/web-platform-tests/XMLHttpRequest/FormData-append.html @@ -1,28 +1,94 @@ - + FormData.append - - - -
+ + + +
+
diff --git a/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-delete.htm b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-delete.htm new file mode 100644 index 00000000000..283b44b5ab0 --- /dev/null +++ b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-delete.htm @@ -0,0 +1,65 @@ + + + +FormData: delete + + + + +
+ + + +
+
+ + +
+
+ diff --git a/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-get.htm b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-get.htm new file mode 100644 index 00000000000..b71a72fa9bc --- /dev/null +++ b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-get.htm @@ -0,0 +1,60 @@ + + + +FormData: get and getAll + + + + +
+ + + +
+
+ diff --git a/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-has.htm b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-has.htm new file mode 100644 index 00000000000..ecd22b4e30b --- /dev/null +++ b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-has.htm @@ -0,0 +1,42 @@ + + + +FormData: has + + + + +
+ + + +
+
+ diff --git a/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-set.htm b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-set.htm new file mode 100644 index 00000000000..2ad33d970db --- /dev/null +++ b/tests/wpt/web-platform-tests/XMLHttpRequest/formdata-set.htm @@ -0,0 +1,94 @@ + + +FormData: set + + + +
+ +