Bug 1795723 - Unified extensions UI should support High Contrast Mode. r=ayeddi,deskt...
[gecko.git] / dom / html / HTMLFormSubmission.h
blob8968fee18752f074e45c101e83cea29198fcaf83
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_HTMLFormSubmission_h
8 #define mozilla_dom_HTMLFormSubmission_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/dom/UserActivation.h"
12 #include "mozilla/dom/HTMLDialogElement.h"
13 #include "nsCOMPtr.h"
14 #include "mozilla/Encoding.h"
15 #include "nsString.h"
17 class nsIURI;
18 class nsIInputStream;
19 class nsGenericHTMLElement;
20 class nsIMultiplexInputStream;
22 namespace mozilla::dom {
24 class Blob;
25 class DialogFormSubmission;
26 class Directory;
27 class Element;
28 class HTMLFormElement;
30 /**
31 * Class for form submissions; encompasses the function to call to submit as
32 * well as the form submission name/value pairs
34 class HTMLFormSubmission {
35 public:
36 /**
37 * Get a submission object based on attributes in the form (ENCTYPE and
38 * METHOD)
40 * @param aForm the form to get a submission object based on
41 * @param aSubmitter the submitter element (can be null)
42 * @param aFormSubmission the form submission object (out param)
44 static nsresult GetFromForm(HTMLFormElement* aForm,
45 nsGenericHTMLElement* aSubmitter,
46 NotNull<const Encoding*>& aEncoding,
47 HTMLFormSubmission** aFormSubmission);
49 MOZ_COUNTED_DTOR_VIRTUAL(HTMLFormSubmission)
51 /**
52 * Submit a name/value pair
54 * @param aName the name of the parameter
55 * @param aValue the value of the parameter
57 virtual nsresult AddNameValuePair(const nsAString& aName,
58 const nsAString& aValue) = 0;
60 /**
61 * Submit a name/blob pair
63 * @param aName the name of the parameter
64 * @param aBlob the blob to submit. The file's name will be used if the Blob
65 * is actually a File, otherwise 'blob' string is used instead. Must not be
66 * null.
68 virtual nsresult AddNameBlobPair(const nsAString& aName, Blob* aBlob) = 0;
70 /**
71 * Submit a name/directory pair
73 * @param aName the name of the parameter
74 * @param aBlob the directory to submit.
76 virtual nsresult AddNameDirectoryPair(const nsAString& aName,
77 Directory* aDirectory) = 0;
79 /**
80 * Given a URI and the current submission, create the final URI and data
81 * stream that will be submitted. Subclasses *must* implement this.
83 * @param aURI the URI being submitted to [IN]
84 * @param aPostDataStream a data stream for POST data [OUT]
85 * @param aOutURI the resulting URI. May be the same as aURI [OUT]
87 virtual nsresult GetEncodedSubmission(nsIURI* aURI,
88 nsIInputStream** aPostDataStream,
89 nsCOMPtr<nsIURI>& aOutURI) = 0;
91 /**
92 * Get the charset that will be used for submission.
94 void GetCharset(nsACString& aCharset) { mEncoding->Name(aCharset); }
96 /**
97 * Get the action URI that will be used for submission.
99 nsIURI* GetActionURL() const { return mActionURL; }
102 * Get the target that will be used for submission.
104 void GetTarget(nsAString& aTarget) { aTarget = mTarget; }
107 * Return true if this form submission was user-initiated.
109 bool IsInitiatedFromUserInput() const { return mInitiatedFromUserInput; }
111 virtual DialogFormSubmission* GetAsDialogSubmission() { return nullptr; }
113 protected:
115 * Can only be constructed by subclasses.
117 * @param aEncoding the character encoding of the form
119 HTMLFormSubmission(nsIURI* aActionURL, const nsAString& aTarget,
120 mozilla::NotNull<const mozilla::Encoding*> aEncoding);
122 // The action url.
123 nsCOMPtr<nsIURI> mActionURL;
125 // The target.
126 nsString mTarget;
128 // The character encoding of this form submission
129 mozilla::NotNull<const mozilla::Encoding*> mEncoding;
131 // Keep track of whether this form submission was user-initiated or not
132 bool mInitiatedFromUserInput;
135 class EncodingFormSubmission : public HTMLFormSubmission {
136 public:
137 EncodingFormSubmission(nsIURI* aActionURL, const nsAString& aTarget,
138 mozilla::NotNull<const mozilla::Encoding*> aEncoding,
139 Element* aSubmitter);
141 virtual ~EncodingFormSubmission();
143 // Indicates the type of newline normalization and escaping to perform in
144 // `EncodeVal`, in addition to encoding the string into bytes.
145 enum EncodeType {
146 // Normalizes newlines to CRLF and then escapes for use in
147 // `Content-Disposition`. (Useful for `multipart/form-data` entry names.)
148 eNameEncode,
149 // Escapes for use in `Content-Disposition`. (Useful for
150 // `multipart/form-data` filenames.)
151 eFilenameEncode,
152 // Normalizes newlines to CRLF.
153 eValueEncode,
157 * Encode a Unicode string to bytes, additionally performing escapes or
158 * normalizations.
159 * @param aStr the string to encode
160 * @param aOut the encoded string [OUT]
161 * @param aEncodeType The type of escapes or normalizations to perform on the
162 * encoded string.
163 * @throws an error if UnicodeToNewBytes fails
165 nsresult EncodeVal(const nsAString& aStr, nsCString& aOut,
166 EncodeType aEncodeType);
169 class DialogFormSubmission final : public HTMLFormSubmission {
170 public:
171 DialogFormSubmission(nsAString& aResult, nsIURI* aActionURL,
172 const nsAString& aTarget,
173 NotNull<const Encoding*> aEncoding,
174 HTMLDialogElement* aDialogElement)
175 : HTMLFormSubmission(aActionURL, aTarget, aEncoding),
176 mDialogElement(aDialogElement),
177 mReturnValue(aResult) {}
178 nsresult AddNameValuePair(const nsAString& aName,
179 const nsAString& aValue) override {
180 MOZ_CRASH("This method should not be called");
181 return NS_OK;
184 nsresult AddNameBlobPair(const nsAString& aName, Blob* aBlob) override {
185 MOZ_CRASH("This method should not be called");
186 return NS_OK;
189 nsresult AddNameDirectoryPair(const nsAString& aName,
190 Directory* aDirectory) override {
191 MOZ_CRASH("This method should not be called");
192 return NS_OK;
195 nsresult GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream,
196 nsCOMPtr<nsIURI>& aOutURI) override {
197 MOZ_CRASH("This method should not be called");
198 return NS_OK;
201 DialogFormSubmission* GetAsDialogSubmission() override { return this; }
203 HTMLDialogElement* DialogElement() { return mDialogElement; }
205 nsString& ReturnValue() { return mReturnValue; }
207 private:
208 const RefPtr<HTMLDialogElement> mDialogElement;
209 nsString mReturnValue;
213 * Handle multipart/form-data encoding, which does files as well as normal
214 * inputs. This always does POST.
216 class FSMultipartFormData : public EncodingFormSubmission {
217 public:
219 * @param aEncoding the character encoding of the form
221 FSMultipartFormData(nsIURI* aActionURL, const nsAString& aTarget,
222 mozilla::NotNull<const mozilla::Encoding*> aEncoding,
223 Element* aSubmitter);
224 ~FSMultipartFormData();
226 virtual nsresult AddNameValuePair(const nsAString& aName,
227 const nsAString& aValue) override;
229 virtual nsresult AddNameBlobPair(const nsAString& aName,
230 Blob* aBlob) override;
232 virtual nsresult AddNameDirectoryPair(const nsAString& aName,
233 Directory* aDirectory) override;
235 virtual nsresult GetEncodedSubmission(nsIURI* aURI,
236 nsIInputStream** aPostDataStream,
237 nsCOMPtr<nsIURI>& aOutURI) override;
239 void GetContentType(nsACString& aContentType) {
240 aContentType = "multipart/form-data; boundary="_ns + mBoundary;
243 nsIInputStream* GetSubmissionBody(uint64_t* aContentLength);
245 protected:
247 * Roll up the data we have so far and add it to the multiplexed data stream.
249 nsresult AddPostDataStream();
251 private:
252 void AddDataChunk(const nsACString& aName, const nsACString& aFilename,
253 const nsACString& aContentType,
254 nsIInputStream* aInputStream, uint64_t aInputStreamSize);
256 * The post data stream as it is so far. This is a collection of smaller
257 * chunks--string streams and file streams interleaved to make one big POST
258 * stream.
260 nsCOMPtr<nsIMultiplexInputStream> mPostData;
263 * The same stream, but as an nsIInputStream.
264 * Raw pointers because it is just QI of mInputStream.
266 nsIInputStream* mPostDataStream;
269 * The current string chunk. When a file is hit, the string chunk gets
270 * wrapped up into an input stream and put into mPostDataStream so that the
271 * file input stream can then be appended and everything is in the right
272 * order. Then the string chunk gets appended to again as we process more
273 * name/value pairs.
275 nsCString mPostDataChunk;
278 * The boundary string to use after each "part" (the boundary that marks the
279 * end of a value). This is computed randomly and is different for each
280 * submission.
282 nsCString mBoundary;
285 * The total length in bytes of the streams that make up mPostDataStream
287 uint64_t mTotalLength;
290 } // namespace mozilla::dom
292 #endif /* mozilla_dom_HTMLFormSubmission_h */