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/. */
7 #ifndef mozilla_dom_FormData_h
8 #define mozilla_dom_FormData_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/dom/BindingDeclarations.h"
12 #include "mozilla/dom/HTMLFormSubmission.h"
13 #include "mozilla/dom/File.h"
14 #include "mozilla/dom/FormDataBinding.h"
15 #include "nsGenericHTMLElement.h"
17 #include "nsWrapperCache.h"
24 class CustomElementFormValue
;
25 class HTMLFormElement
;
28 class FormData final
: public nsISupports
,
29 public HTMLFormSubmission
,
30 public nsWrapperCache
{
32 FormData(const FormData
& aFormData
);
33 ~FormData() = default;
35 struct FormDataTuple
{
37 OwningBlobOrDirectoryOrUSVString value
;
40 // Returns the FormDataTuple to modify. This may be null, in which case
41 // no element with aName was found.
42 FormDataTuple
* RemoveAllOthersAndGetFirstFormDataTuple(
43 const nsAString
& aName
);
45 void SetNameValuePair(FormDataTuple
* aData
, const nsAString
& aName
,
46 const nsAString
& aValue
);
48 void SetNameFilePair(FormDataTuple
* aData
, const nsAString
& aName
,
51 void SetNameDirectoryPair(FormDataTuple
* aData
, const nsAString
& aName
,
52 Directory
* aDirectory
);
55 explicit FormData(nsISupports
* aOwner
= nullptr,
56 NotNull
<const Encoding
*> aEncoding
= UTF_8_ENCODING
,
57 Element
* aSubmitter
= nullptr);
59 already_AddRefed
<FormData
> Clone();
61 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
62 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(FormData
)
65 virtual JSObject
* WrapObject(JSContext
* aCx
,
66 JS::Handle
<JSObject
*> aGivenProto
) override
;
69 nsISupports
* GetParentObject() const { return mOwner
; }
71 static already_AddRefed
<FormData
> Constructor(
72 const GlobalObject
& aGlobal
,
73 const Optional
<NonNull
<HTMLFormElement
> >& aFormElement
,
74 nsGenericHTMLElement
* aSubmitter
, ErrorResult
& aRv
);
76 void Append(const nsAString
& aName
, const nsAString
& aValue
,
79 void Append(const nsAString
& aName
, Blob
& aBlob
,
80 const Optional
<nsAString
>& aFilename
, ErrorResult
& aRv
);
82 void Append(const nsAString
& aName
, Directory
* aDirectory
);
84 void Append(const FormData
& aFormData
);
86 void Delete(const nsAString
& aName
);
88 void Get(const nsAString
& aName
,
89 Nullable
<OwningBlobOrDirectoryOrUSVString
>& aOutValue
);
91 void GetAll(const nsAString
& aName
,
92 nsTArray
<OwningBlobOrDirectoryOrUSVString
>& aValues
);
94 bool Has(const nsAString
& aName
);
96 void Set(const nsAString
& aName
, Blob
& aBlob
,
97 const Optional
<nsAString
>& aFilename
, ErrorResult
& aRv
);
98 void Set(const nsAString
& aName
, const nsAString
& aValue
, ErrorResult
& aRv
);
100 uint32_t GetIterableLength() const;
102 const nsAString
& GetKeyAtIndex(uint32_t aIndex
) const;
104 const OwningBlobOrDirectoryOrUSVString
& GetValueAtIndex(
105 uint32_t aIndex
) const;
107 // HTMLFormSubmission
108 virtual nsresult
GetEncodedSubmission(nsIURI
* aURI
,
109 nsIInputStream
** aPostDataStream
,
110 nsCOMPtr
<nsIURI
>& aOutURI
) override
;
112 virtual nsresult
AddNameValuePair(const nsAString
& aName
,
113 const nsAString
& aValue
) override
{
114 nsAutoString
usvName(aName
);
115 nsAutoString
usvValue(aValue
);
116 if (!NormalizeUSVString(usvName
) || !NormalizeUSVString(usvValue
)) {
117 return NS_ERROR_OUT_OF_MEMORY
;
120 FormDataTuple
* data
= mFormData
.AppendElement();
121 SetNameValuePair(data
, usvName
, usvValue
);
125 virtual nsresult
AddNameBlobPair(const nsAString
& aName
,
126 Blob
* aBlob
) override
;
128 virtual nsresult
AddNameDirectoryPair(const nsAString
& aName
,
129 Directory
* aDirectory
) override
;
131 uint32_t Length() const { return mFormData
.Length(); }
133 // Stops iteration and returns false if any invocation of callback returns
134 // false. Returns true otherwise.
135 // Accepts callbacks of the form `bool(const nsString&, const
136 // OwningBlobOrDirectoryOrUSVString&)`.
137 template <typename F
>
138 bool ForEach(F
&& aCallback
) {
139 for (uint32_t i
= 0; i
< mFormData
.Length(); ++i
) {
140 FormDataTuple
& tuple
= mFormData
[i
];
141 if (!aCallback(tuple
.name
, tuple
.value
)) {
149 nsresult
GetSendInfo(nsIInputStream
** aBody
, uint64_t* aContentLength
,
150 nsACString
& aContentTypeWithCharset
,
151 nsACString
& aCharset
) const;
153 nsresult
CopySubmissionDataTo(HTMLFormSubmission
* aFormSubmission
) const;
155 Element
* GetSubmitterElement() const { return mSubmitter
.get(); }
157 CustomElementFormValue
ConvertToCustomElementFormValue();
160 nsCOMPtr
<nsISupports
> mOwner
;
162 // Submitter element.
163 RefPtr
<Element
> mSubmitter
;
165 nsTArray
<FormDataTuple
> mFormData
;
169 } // namespace mozilla
171 #endif // mozilla_dom_FormData_h