зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1556358 - Allow FormData::ForEach to take a closure instead of a raw function pointer. r=edgar
Depends on D174114 Differential Revision: https://phabricator.services.mozilla.com/D175542
This commit is contained in:
Родитель
216d5131c8
Коммит
0bf288bb5c
|
@ -127,18 +127,17 @@ class FormData final : public nsISupports,
|
|||
virtual nsresult AddNameDirectoryPair(const nsAString& aName,
|
||||
Directory* aDirectory) override;
|
||||
|
||||
using FormDataEntryCallback =
|
||||
bool (*)(const nsString& aName,
|
||||
const OwningBlobOrDirectoryOrUSVString& aValue, void* aClosure);
|
||||
|
||||
uint32_t Length() const { return mFormData.Length(); }
|
||||
|
||||
// Stops iteration and returns false if any invocation of callback returns
|
||||
// false. Returns true otherwise.
|
||||
bool ForEach(FormDataEntryCallback aFunc, void* aClosure) {
|
||||
// Accepts callbacks of the form `bool(const nsString&, const
|
||||
// OwningBlobOrDirectoryOrUSVString&)`.
|
||||
template <typename F>
|
||||
bool ForEach(F&& aCallback) {
|
||||
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
|
||||
FormDataTuple& tuple = mFormData[i];
|
||||
if (!aFunc(tuple.name, tuple.value, aClosure)) {
|
||||
if (!aCallback(tuple.name, tuple.value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -896,52 +896,36 @@ bool WriteFormData(JSStructuredCloneWriter* aWriter, FormData* aFormData,
|
|||
return false;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS Closure final {
|
||||
JSStructuredCloneWriter* mWriter;
|
||||
StructuredCloneHolder* mHolder;
|
||||
auto write = [aWriter, aHolder](
|
||||
const nsString& aName,
|
||||
const OwningBlobOrDirectoryOrUSVString& aValue) {
|
||||
if (!StructuredCloneHolder::WriteString(aWriter, aName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
Closure(JSStructuredCloneWriter* aWriter, StructuredCloneHolder* aHolder)
|
||||
: mWriter(aWriter), mHolder(aHolder) {}
|
||||
|
||||
static bool Write(const nsString& aName,
|
||||
const OwningBlobOrDirectoryOrUSVString& aValue,
|
||||
void* aClosure) {
|
||||
Closure* closure = static_cast<Closure*>(aClosure);
|
||||
if (!StructuredCloneHolder::WriteString(closure->mWriter, aName)) {
|
||||
if (aValue.IsBlob()) {
|
||||
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
|
||||
aHolder->BlobImpls().Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aValue.IsBlob()) {
|
||||
if (!JS_WriteUint32Pair(closure->mWriter, SCTAG_DOM_BLOB,
|
||||
closure->mHolder->BlobImpls().Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<BlobImpl> blobImpl = aValue.GetAsBlob()->Impl();
|
||||
|
||||
closure->mHolder->BlobImpls().AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aValue.IsDirectory()) {
|
||||
Directory* directory = aValue.GetAsDirectory();
|
||||
return WriteDirectory(closure->mWriter, directory);
|
||||
}
|
||||
|
||||
size_t charSize = sizeof(nsString::char_type);
|
||||
if (!JS_WriteUint32Pair(closure->mWriter, 0,
|
||||
aValue.GetAsUSVString().Length()) ||
|
||||
!JS_WriteBytes(closure->mWriter, aValue.GetAsUSVString().get(),
|
||||
aValue.GetAsUSVString().Length() * charSize)) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<BlobImpl> blobImpl = aValue.GetAsBlob()->Impl();
|
||||
|
||||
aHolder->BlobImpls().AppendElement(blobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aValue.IsDirectory()) {
|
||||
Directory* directory = aValue.GetAsDirectory();
|
||||
return WriteDirectory(aWriter, directory);
|
||||
}
|
||||
|
||||
const size_t charSize = sizeof(nsString::char_type);
|
||||
return JS_WriteUint32Pair(aWriter, 0, aValue.GetAsUSVString().Length()) &&
|
||||
JS_WriteBytes(aWriter, aValue.GetAsUSVString().get(),
|
||||
aValue.GetAsUSVString().Length() * charSize);
|
||||
};
|
||||
Closure closure(aWriter, aHolder);
|
||||
return aFormData->ForEach(Closure::Write, &closure);
|
||||
return aFormData->ForEach(write);
|
||||
}
|
||||
|
||||
JSObject* ReadWasmModule(JSContext* aCx, uint32_t aIndex,
|
||||
|
|
Загрузка…
Ссылка в новой задаче