FormData.h (5620B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_FormData_h 8 #define mozilla_dom_FormData_h 9 10 #include "mozilla/dom/BindingDeclarations.h" 11 #include "mozilla/dom/File.h" 12 #include "mozilla/dom/FormDataBinding.h" 13 #include "mozilla/dom/HTMLFormSubmission.h" 14 #include "nsGenericHTMLElement.h" 15 #include "nsTArray.h" 16 #include "nsWrapperCache.h" 17 18 namespace mozilla { 19 class ErrorResult; 20 21 namespace dom { 22 23 class CustomElementFormValue; 24 class HTMLFormElement; 25 class GlobalObject; 26 27 class FormData final : public nsISupports, 28 public HTMLFormSubmission, 29 public nsWrapperCache { 30 private: 31 FormData(const FormData& aFormData); 32 ~FormData() = default; 33 34 struct FormDataTuple { 35 nsString name; 36 OwningBlobOrDirectoryOrUSVString value; 37 }; 38 39 // Returns the FormDataTuple to modify. This may be null, in which case 40 // no element with aName was found. 41 FormDataTuple* RemoveAllOthersAndGetFirstFormDataTuple( 42 const nsAString& aName); 43 44 void SetNameValuePair(FormDataTuple* aData, const nsAString& aName, 45 const nsAString& aValue); 46 47 void SetNameFilePair(FormDataTuple* aData, const nsAString& aName, 48 File* aFile); 49 50 void SetNameDirectoryPair(FormDataTuple* aData, const nsAString& aName, 51 Directory* aDirectory); 52 53 public: 54 explicit FormData(nsISupports* aOwner = nullptr, 55 NotNull<const Encoding*> aEncoding = UTF_8_ENCODING, 56 Element* aSubmitter = nullptr); 57 58 already_AddRefed<FormData> Clone() const; 59 60 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 61 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(FormData) 62 63 // nsWrapperCache 64 virtual JSObject* WrapObject(JSContext* aCx, 65 JS::Handle<JSObject*> aGivenProto) override; 66 67 // WebIDL 68 nsISupports* GetParentObject() const { return mOwner; } 69 70 static already_AddRefed<FormData> Constructor( 71 const GlobalObject& aGlobal, 72 const Optional<NonNull<HTMLFormElement> >& aFormElement, 73 nsGenericHTMLElement* aSubmitter, ErrorResult& aRv); 74 75 static already_AddRefed<FormData> Constructor( 76 nsISupports* aGlobal, HTMLFormElement* aFormElement, 77 nsGenericHTMLElement* aSubmitter, ErrorResult& aRv); 78 79 void Append(const nsAString& aName, const nsAString& aValue, 80 ErrorResult& aRv); 81 82 void Append(const nsAString& aName, Blob& aBlob, 83 const Optional<nsAString>& aFilename, ErrorResult& aRv); 84 85 void Append(const nsAString& aName, Directory* aDirectory); 86 87 void Append(const FormData& aFormData); 88 89 void Delete(const nsAString& aName); 90 91 void Get(const nsAString& aName, 92 Nullable<OwningBlobOrDirectoryOrUSVString>& aOutValue); 93 94 void GetAll(const nsAString& aName, 95 nsTArray<OwningBlobOrDirectoryOrUSVString>& aValues); 96 97 bool Has(const nsAString& aName); 98 99 void Set(const nsAString& aName, Blob& aBlob, 100 const Optional<nsAString>& aFilename, ErrorResult& aRv); 101 void Set(const nsAString& aName, const nsAString& aValue, ErrorResult& aRv); 102 103 uint32_t GetIterableLength() const; 104 105 const nsAString& GetKeyAtIndex(uint32_t aIndex) const; 106 107 const OwningBlobOrDirectoryOrUSVString& GetValueAtIndex( 108 uint32_t aIndex) const; 109 110 // HTMLFormSubmission 111 virtual nsresult GetEncodedSubmission(nsIURI* aURI, 112 nsIInputStream** aPostDataStream, 113 nsCOMPtr<nsIURI>& aOutURI) override; 114 115 virtual nsresult AddNameValuePair(const nsAString& aName, 116 const nsAString& aValue) override { 117 nsAutoString usvName(aName); 118 nsAutoString usvValue(aValue); 119 if (!NormalizeUSVString(usvName) || !NormalizeUSVString(usvValue)) { 120 return NS_ERROR_OUT_OF_MEMORY; 121 } 122 123 FormDataTuple* data = mFormData.AppendElement(); 124 SetNameValuePair(data, usvName, usvValue); 125 return NS_OK; 126 } 127 128 virtual nsresult AddNameBlobPair(const nsAString& aName, 129 Blob* aBlob) override; 130 131 virtual nsresult AddNameDirectoryPair(const nsAString& aName, 132 Directory* aDirectory) override; 133 134 uint32_t Length() const { return mFormData.Length(); } 135 136 // Stops iteration and returns false if any invocation of callback returns 137 // false. Returns true otherwise. 138 // Accepts callbacks of the form `bool(const nsString&, const 139 // OwningBlobOrDirectoryOrUSVString&)`. 140 template <typename F> 141 bool ForEach(F&& aCallback) { 142 for (uint32_t i = 0; i < mFormData.Length(); ++i) { 143 FormDataTuple& tuple = mFormData[i]; 144 if (!aCallback(tuple.name, tuple.value)) { 145 return false; 146 } 147 } 148 149 return true; 150 } 151 152 nsresult GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength, 153 nsACString& aContentTypeWithCharset, 154 nsACString& aCharset) const; 155 156 nsresult CopySubmissionDataTo(HTMLFormSubmission* aFormSubmission) const; 157 158 Element* GetSubmitterElement() const { return mSubmitter.get(); } 159 160 CustomElementFormValue ConvertToCustomElementFormValue(); 161 162 private: 163 nsCOMPtr<nsISupports> mOwner; 164 165 // Submitter element. 166 RefPtr<Element> mSubmitter; 167 168 nsTArray<FormDataTuple> mFormData; 169 }; 170 171 } // namespace dom 172 } // namespace mozilla 173 174 #endif // mozilla_dom_FormData_h