michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsFormData.h" michael@0: #include "nsIVariant.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsIDOMFile.h" michael@0: #include "mozilla/dom/HTMLFormElement.h" michael@0: #include "mozilla/dom/FormDataBinding.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: nsFormData::nsFormData(nsISupports* aOwner) michael@0: : nsFormSubmission(NS_LITERAL_CSTRING("UTF-8"), nullptr) michael@0: , mOwner(aOwner) michael@0: { michael@0: SetIsDOMBinding(); michael@0: } michael@0: michael@0: // ------------------------------------------------------------------------- michael@0: // nsISupports michael@0: michael@0: NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsFormData, mOwner) michael@0: NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFormData) michael@0: NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFormData) michael@0: NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFormData) michael@0: NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY michael@0: NS_INTERFACE_MAP_ENTRY(nsIDOMFormData) michael@0: NS_INTERFACE_MAP_ENTRY(nsIXHRSendable) michael@0: NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFormData) michael@0: NS_INTERFACE_MAP_END michael@0: michael@0: // ------------------------------------------------------------------------- michael@0: // nsFormSubmission michael@0: nsresult michael@0: nsFormData::GetEncodedSubmission(nsIURI* aURI, michael@0: nsIInputStream** aPostDataStream) michael@0: { michael@0: NS_NOTREACHED("Shouldn't call nsFormData::GetEncodedSubmission"); michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: nsFormData::Append(const nsAString& aName, const nsAString& aValue) michael@0: { michael@0: AddNameValuePair(aName, aValue); michael@0: } michael@0: michael@0: void michael@0: nsFormData::Append(const nsAString& aName, nsIDOMBlob* aBlob, michael@0: const Optional& aFilename) michael@0: { michael@0: nsString filename; michael@0: if (aFilename.WasPassed()) { michael@0: filename = aFilename.Value(); michael@0: } else { michael@0: filename.SetIsVoid(true); michael@0: } michael@0: AddNameFilePair(aName, aBlob, filename); michael@0: } michael@0: michael@0: // ------------------------------------------------------------------------- michael@0: // nsIDOMFormData michael@0: michael@0: NS_IMETHODIMP michael@0: nsFormData::Append(const nsAString& aName, nsIVariant* aValue) michael@0: { michael@0: uint16_t dataType; michael@0: nsresult rv = aValue->GetDataType(&dataType); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (dataType == nsIDataType::VTYPE_INTERFACE || michael@0: dataType == nsIDataType::VTYPE_INTERFACE_IS) { michael@0: nsCOMPtr supports; michael@0: nsID *iid; michael@0: rv = aValue->GetAsInterface(&iid, getter_AddRefs(supports)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsMemory::Free(iid); michael@0: michael@0: nsCOMPtr domBlob = do_QueryInterface(supports); michael@0: if (domBlob) { michael@0: Optional temp; michael@0: Append(aName, domBlob, temp); michael@0: return NS_OK; michael@0: } michael@0: } michael@0: michael@0: char16_t* stringData = nullptr; michael@0: uint32_t stringLen = 0; michael@0: rv = aValue->GetAsWStringWithSize(&stringLen, &stringData); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsString valAsString; michael@0: valAsString.Adopt(stringData, stringLen); michael@0: michael@0: Append(aName, valAsString); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* virtual */ JSObject* michael@0: nsFormData::WrapObject(JSContext* aCx) michael@0: { michael@0: return FormDataBinding::Wrap(aCx, this); michael@0: } michael@0: michael@0: /* static */ already_AddRefed michael@0: nsFormData::Constructor(const GlobalObject& aGlobal, michael@0: const Optional >& aFormElement, michael@0: ErrorResult& aRv) michael@0: { michael@0: nsRefPtr formData = new nsFormData(aGlobal.GetAsSupports()); michael@0: if (aFormElement.WasPassed()) { michael@0: aRv = aFormElement.Value().WalkFormElements(formData); michael@0: } michael@0: return formData.forget(); michael@0: } michael@0: michael@0: // ------------------------------------------------------------------------- michael@0: // nsIXHRSendable michael@0: michael@0: NS_IMETHODIMP michael@0: nsFormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength, michael@0: nsACString& aContentType, nsACString& aCharset) michael@0: { michael@0: nsFSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr); michael@0: michael@0: for (uint32_t i = 0; i < mFormData.Length(); ++i) { michael@0: if (mFormData[i].valueIsFile) { michael@0: fs.AddNameFilePair(mFormData[i].name, mFormData[i].fileValue, michael@0: mFormData[i].filename); michael@0: } michael@0: else { michael@0: fs.AddNameValuePair(mFormData[i].name, mFormData[i].stringValue); michael@0: } michael@0: } michael@0: michael@0: fs.GetContentType(aContentType); michael@0: aCharset.Truncate(); michael@0: *aContentLength = 0; michael@0: NS_ADDREF(*aBody = fs.GetSubmissionBody(aContentLength)); michael@0: michael@0: return NS_OK; michael@0: }