Bug 1127703 - Support iteration on FormData, r=bz

This commit is contained in:
Andrea Marchesini 2015-10-19 16:16:42 +01:00
Родитель 43780d35db
Коммит c94d30fc34
5 изменённых файлов: 102 добавлений и 36 удалений

Просмотреть файл

@ -862,16 +862,16 @@ WriteFormData(JSStructuredCloneWriter* aWriter,
{ }
static bool
Write(const nsString& aName, bool isFile, const nsString& aValue,
File* aFile, void* aClosure)
Write(const nsString& aName, const OwningFileOrUSVString& aValue,
void* aClosure)
{
Closure* closure = static_cast<Closure*>(aClosure);
if (!WriteString(closure->mWriter, aName)) {
return false;
}
if (isFile) {
BlobImpl* blobImpl = aFile->Impl();
if (aValue.IsFile()) {
BlobImpl* blobImpl = aValue.GetAsFile()->Impl();
if (!JS_WriteUint32Pair(closure->mWriter, SCTAG_DOM_BLOB,
closure->mHolder->BlobImpls().Length())) {
return false;
@ -882,9 +882,10 @@ WriteFormData(JSStructuredCloneWriter* aWriter,
}
size_t charSize = sizeof(nsString::char_type);
if (!JS_WriteUint32Pair(closure->mWriter, 0, aValue.Length()) ||
!JS_WriteBytes(closure->mWriter, aValue.get(),
aValue.Length() * charSize)) {
if (!JS_WriteUint32Pair(closure->mWriter, 0,
aValue.GetAsUSVString().Length()) ||
!JS_WriteBytes(closure->mWriter, aValue.GetAsUSVString().get(),
aValue.GetAsUSVString().Length() * charSize)) {
return false;
}

Просмотреть файл

@ -61,7 +61,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFormData)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
ImplCycleCollectionUnlink(tmp->mFormData[i].fileValue);
if (tmp->mFormData[i].value.IsFile()) {
ImplCycleCollectionUnlink(tmp->mFormData[i].value);
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
@ -71,8 +73,8 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFormData)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
for (uint32_t i = 0, len = tmp->mFormData.Length(); i < len; ++i) {
ImplCycleCollectionTraverse(cb,tmp->mFormData[i].fileValue,
"mFormData[i].fileValue", 0);
ImplCycleCollectionTraverse(cb, tmp->mFormData[i].value,
"mFormData[i].GetAsFile()", 0);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
@ -126,24 +128,13 @@ nsFormData::Delete(const nsAString& aName)
}
}
void
nsFormData::ExtractValue(const FormDataTuple& aTuple,
OwningFileOrUSVString* aOutValue)
{
if (aTuple.valueIsFile) {
aOutValue->SetAsFile() = aTuple.fileValue;
} else {
aOutValue->SetAsUSVString() = aTuple.stringValue;
}
}
void
nsFormData::Get(const nsAString& aName,
Nullable<OwningFileOrUSVString>& aOutValue)
{
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
if (aName.Equals(mFormData[i].name)) {
ExtractValue(mFormData[i], &aOutValue.SetValue());
aOutValue.SetValue() = mFormData[i].value;
return;
}
}
@ -158,7 +149,7 @@ nsFormData::GetAll(const nsAString& aName,
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
if (aName.Equals(mFormData[i].name)) {
OwningFileOrUSVString* element = aValues.AppendElement();
ExtractValue(mFormData[i], element);
*element = mFormData[i].value;
}
}
}
@ -229,6 +220,26 @@ nsFormData::Set(const nsAString& aName, const nsAString& aValue)
}
}
uint32_t
nsFormData::GetIterableLength() const
{
return mFormData.Length();
}
const nsAString&
nsFormData::GetKeyAtIndex(uint32_t aIndex) const
{
MOZ_ASSERT(aIndex < mFormData.Length());
return mFormData[aIndex].name;
}
const OwningFileOrUSVString&
nsFormData::GetValueAtIndex(uint32_t aIndex) const
{
MOZ_ASSERT(aIndex < mFormData.Length());
return mFormData[aIndex].value;
}
// -------------------------------------------------------------------------
// nsIDOMFormData
@ -297,11 +308,11 @@ nsFormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
nsFSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr);
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
if (mFormData[i].valueIsFile) {
fs.AddNameFilePair(mFormData[i].name, mFormData[i].fileValue);
}
else {
fs.AddNameValuePair(mFormData[i].name, mFormData[i].stringValue);
if (mFormData[i].value.IsFile()) {
fs.AddNameFilePair(mFormData[i].name, mFormData[i].value.GetAsFile());
} else {
fs.AddNameValuePair(mFormData[i].name,
mFormData[i].value.GetAsUSVString());
}
}

Просмотреть файл

@ -100,13 +100,17 @@ public:
void Append(const nsAString& aName, Blob& aBlob,
const mozilla::dom::Optional<nsAString>& aFilename);
void Delete(const nsAString& aName);
void Get(const nsAString& aName, mozilla::dom::Nullable<mozilla::dom::OwningFileOrUSVString>& aOutValue);
void GetAll(const nsAString& aName, nsTArray<mozilla::dom::OwningFileOrUSVString>& aValues);
void Get(const nsAString& aName, mozilla::dom::Nullable<OwningFileOrUSVString>& aOutValue);
void GetAll(const nsAString& aName, nsTArray<OwningFileOrUSVString>& aValues);
bool Has(const nsAString& aName);
void Set(const nsAString& aName, Blob& aBlob,
const mozilla::dom::Optional<nsAString>& aFilename);
void Set(const nsAString& aName, const nsAString& aValue);
uint32_t GetIterableLength() const;
const nsAString& GetKeyAtIndex(uint32_t aIndex) const;
const OwningFileOrUSVString& GetValueAtIndex(uint32_t aIndex) const;
// nsFormSubmission
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream) override;
@ -120,9 +124,9 @@ public:
virtual nsresult AddNameFilePair(const nsAString& aName,
File* aFile) override;
typedef bool (*FormDataEntryCallback)(const nsString& aName, bool aIsFile,
const nsString& aValue,
File* aFile, void* aClosure);
typedef bool (*FormDataEntryCallback)(const nsString& aName,
const OwningFileOrUSVString& aValue,
void* aClosure);
uint32_t
Length() const
@ -137,8 +141,7 @@ public:
{
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
FormDataTuple& tuple = mFormData[i];
if (!aFunc(tuple.name, tuple.valueIsFile, tuple.stringValue,
tuple.fileValue, aClosure)) {
if (!aFunc(tuple.name, tuple.value, aClosure)) {
return false;
}
}

Просмотреть файл

@ -105,6 +105,56 @@ function testFilename() {
is(f.get("file3").name, "", "File's filename is returned even if empty.");
}
function testIterable() {
var fd = new FormData();
fd.set('1','2');
fd.set('2','4');
fd.set('3','6');
fd.set('4','8');
fd.set('5','10');
var key_iter = fd.keys();
var value_iter = fd.values();
var entries_iter = fd.entries();
for (var i = 0; i < 5; ++i) {
var v = i + 1;
var key = key_iter.next();
var value = value_iter.next();
var entry = entries_iter.next();
is(key.value, v.toString(), "Correct Key iterator: " + v.toString());
ok(!key.done, "key.done is false");
is(value.value, (v * 2).toString(), "Correct Value iterator: " + (v * 2).toString());
ok(!value.done, "value.done is false");
is(entry.value[0], v.toString(), "Correct Entry 0 iterator: " + v.toString());
is(entry.value[1], (v * 2).toString(), "Correct Entry 1 iterator: " + (v * 2).toString());
ok(!entry.done, "entry.done is false");
}
var last = key_iter.next();
ok(last.done, "Nothing more to read.");
is(last.value, undefined, "Undefined is the last key");
last = value_iter.next();
ok(last.done, "Nothing more to read.");
is(last.value, undefined, "Undefined is the last value");
last = entries_iter.next();
ok(last.done, "Nothing more to read.");
key_iter = fd.keys();
key_iter.next();
key_iter.next();
fd.delete('1');
fd.delete('2');
fd.delete('3');
fd.delete('4');
fd.delete('5');
last = key_iter.next();
ok(last.done, "Nothing more to read.");
is(last.value, undefined, "Undefined is the last key");
}
function testSend(doneCb) {
var xhr = new XMLHttpRequest();
xhr.open("POST", "form_submit_server.sjs");
@ -161,6 +211,7 @@ function runTest(doneCb) {
testSet();
testIterate();
testFilename();
testIterable();
// Finally, send an XHR and verify the response matches.
testSend(doneCb);
}

Просмотреть файл

@ -20,5 +20,5 @@ interface FormData {
boolean has(USVString name);
void set(USVString name, Blob value, optional USVString filename);
void set(USVString name, USVString value);
// iterable<USVString, FormDataEntryValue>; - Bug 1127703
iterable<USVString, FormDataEntryValue>;
};