Bug 544698 part 1: Move value processing from submission code to elements. Decomtaminate. Kill a few dead functions. r=jst

This commit is contained in:
Jonas Sicking 2010-02-24 21:58:16 -08:00
parent dcbd30a767
commit 12091aa8ea
17 changed files with 390 additions and 744 deletions

View File

@ -69,6 +69,7 @@ GK_ATOM(mozgeneratedcontentbefore, "_moz_generated_content_before")
GK_ATOM(mozgeneratedcontentafter, "_moz_generated_content_after")
GK_ATOM(mozgeneratedcontentimage, "_moz_generated_content_image")
GK_ATOM(_moz_target, "_moz_target")
GK_ATOM(_moz_type, "_moz-type")
GK_ATOM(menuactive, "_moz-menuactive")
GK_ATOM(_poundDefault, "#default")
GK_ATOM(_asterix, "*")

View File

@ -44,7 +44,7 @@ class nsPresState;
class nsIContent;
class nsString;
class nsIFormProcessor;
class nsIFormSubmission;
class nsFormSubmission;
#define NS_FORM_BUTTON_BUTTON 1
#define NS_FORM_BUTTON_RESET 2
@ -129,7 +129,7 @@ public:
* @param aSubmitElement the element that was pressed to submit (possibly
* null)
*/
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement) = 0;
/**

View File

@ -38,8 +38,9 @@
#define nsIFormSubmission_h___
#include "nsISupports.h"
class nsAString;
class nsACString;
#include "nsString.h"
#include "nsCOMPtr.h"
class nsIURI;
class nsIInputStream;
class nsGenericHTMLElement;
@ -49,27 +50,23 @@ class nsIFormControl;
class nsIDOMHTMLElement;
class nsIDocShell;
class nsIRequest;
#define NS_IFORMSUBMISSION_IID \
{ 0x7ee38e3a, 0x1dd2, 0x11b2, \
{0x89, 0x6f, 0xab, 0x28, 0x03, 0x96, 0x25, 0xa9} }
class nsISaveAsCharset;
/**
* Interface for form submissions; encompasses the function to call to submit as
* Class for form submissions; encompasses the function to call to submit as
* well as the form submission name/value pairs
*/
class nsIFormSubmission : public nsISupports
{
class nsFormSubmission {
public:
virtual ~nsFormSubmission();
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFORMSUBMISSION_IID)
/**
* Find out whether or not this form submission accepts files
*
* @param aAcceptsFiles the boolean output
*/
virtual PRBool AcceptsFiles() const = 0;
void AddRef()
{
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsFormSubmission", sizeof(*this));
}
void Release();
/**
* Call to perform the submission
@ -82,47 +79,87 @@ public:
* loaded
* @param aRequest (out param) the Request for the submission
*/
virtual nsresult SubmitTo(nsIURI* aActionURL, const nsAString& aTarget,
nsIContent* aSource, nsILinkHandler* aLinkHandler,
nsIDocShell** aDocShell,
nsIRequest** aRequest) = 0;
nsresult SubmitTo(nsIURI* aActionURI, const nsAString& aTarget,
nsIContent* aSource, nsILinkHandler* aLinkHandler,
nsIDocShell** aDocShell, nsIRequest** aRequest);
/**
* Submit a name/value pair
*
* @param aSource the control sending the parameter
* @param aName the name of the parameter
* @param aValue the value of the parameter
*/
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue) = 0;
/**
* Submit a name/file pair
*
* @param aSource the control sending the parameter
* @param aName the name of the parameter
* @param aFilename the name of the file (pass null to provide no name)
* @param aStream the stream containing the file data to be sent
* @param aContentType the content-type of the file data being sent
* @param aMoreFilesToCome true if another name/file pair with the same name
* will be sent soon
* @param aFile the file to submit
*/
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome) = 0;
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile) = 0;
/**
* Get the charset that will be used for submission.
*/
void GetCharset(nsACString& aCharset)
{
aCharset = mCharset;
}
protected:
/**
* Can only be constructed by subclasses.
*
* @param aCharset the charset of the form as a string
* @param aEncoder an encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation)
* @param aBidiOptions the BIDI options flags for the current pres context
*/
nsFormSubmission(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
PRInt32 aBidiOptions);
/**
* Given a URI and the current submission, create the final URI and data
* stream that will be submitted. Subclasses *must* implement this.
*
* @param aURI the URI being submitted to [INOUT]
* @param aPostDataStream a data stream for POST data [OUT]
*/
NS_IMETHOD GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream) = 0;
/**
* Encode a Unicode string to bytes using the encoder (or just copy the input
* if there is no encoder).
* @param aStr the string to encode
* @param aResult the encoded string [OUT]
* @throws an error if UnicodeToNewBytes fails
*/
nsresult EncodeVal(const nsAString& aStr, nsACString& aResult);
/**
* Encode a Unicode string to bytes using an encoder. (Used by EncodeVal)
* @param aStr the string to encode
* @param aEncoder the encoder to encode the bytes with (cannot be null)
* @param aOut the encoded string [OUT]
* @throws an error if the encoder fails
*/
nsresult UnicodeToNewBytes(const nsAString& aStr, nsISaveAsCharset* aEncoder,
nsACString& aOut);
nsAutoRefCnt mRefCnt;
// The name of the encoder charset
nsCString mCharset;
// The encoder that will encode Unicode names and values
nsCOMPtr<nsISaveAsCharset> mEncoder;
// The BIDI options flags for the current pres context
PRInt32 mBidiOptions;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFormSubmission, NS_IFORMSUBMISSION_IID)
//
// Factory methods
//
/**
* Get a submission object based on attributes in the form (ENCTYPE and METHOD)
@ -131,7 +168,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIFormSubmission, NS_IFORMSUBMISSION_IID)
* @param aFormSubmission the form submission object (out param)
*/
nsresult GetSubmissionFromForm(nsGenericHTMLElement* aForm,
nsIFormSubmission** aFormSubmission);
nsFormSubmission** aFormSubmission);
#endif /* nsIFormSubmission_h___ */

View File

@ -55,7 +55,6 @@
#include "nsIFile.h"
#include "nsDirectoryServiceDefs.h"
#include "nsStringStream.h"
#include "nsIFormProcessor.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsNetUtil.h"
@ -66,148 +65,43 @@
#include "nsUnicharUtils.h"
#include "nsIMultiplexInputStream.h"
#include "nsIMIMEInputStream.h"
#include "nsIMIMEService.h"
#include "nsIConsoleService.h"
#include "nsIScriptError.h"
#include "nsIStringBundle.h"
//BIDI
#include "nsCExternalHandlerService.h"
#include "nsIFileStreams.h"
#include "nsBidiUtils.h"
//end
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
/**
* Helper superclass implementation of nsIFormSubmission, providing common
* methods that most of the specific implementations need and use.
* Get the submit charset for a form (suitable to pass in to the constructor).
* @param aForm the form in question
* @param aCtrlsModAtSubmit BIDI controls text mode. Unused in non-BIDI
* builds.
* @param aCharset the returned charset [OUT]
*/
class nsFormSubmission : public nsIFormSubmission {
public:
/**
* @param aCharset the charset of the form as a string
* @param aEncoder an encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation)
* @param aFormProcessor a form processor who can listen to
* @param aBidiOptions the BIDI options flags for the current pres context
*/
nsFormSubmission(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions)
: mCharset(aCharset),
mEncoder(aEncoder),
mFormProcessor(aFormProcessor),
mBidiOptions(aBidiOptions)
{
}
virtual ~nsFormSubmission()
{
}
NS_DECL_ISUPPORTS
//
// nsIFormSubmission
//
virtual nsresult SubmitTo(nsIURI* aActionURI, const nsAString& aTarget,
nsIContent* aSource, nsILinkHandler* aLinkHandler,
nsIDocShell** aDocShell, nsIRequest** aRequest);
/**
* Called to initialize the submission. Perform any initialization that may
* fail here. Subclasses *must* implement this.
*/
NS_IMETHOD Init() = 0;
protected:
// this is essentially the nsFormSubmission interface (to be overridden)
/**
* Given a URI and the current submission, create the final URI and data
* stream that will be submitted. Subclasses *must* implement this.
*
* @param aURI the URI being submitted to [INOUT]
* @param aPostDataStream a data stream for POST data [OUT]
*/
NS_IMETHOD GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream) = 0;
// Helpers
/**
* Call to have the form processor listen in when a name/value pair is found
* to be submitted.
*
* @param aSource the HTML element the name/value is associated with
* @param aName the name that will be submitted
* @param aValue the value that will be submitted
* @param the processed value that will be sent to the server. [OUT]
*/
nsresult ProcessValue(nsIDOMHTMLElement* aSource, const nsAString& aName,
const nsAString& aValue, nsAString& aResult);
// Encoding Helpers
/**
* Encode a Unicode string to bytes using the encoder (or just copy the input
* if there is no encoder).
* @param aStr the string to encode
* @param aResult the encoded string [OUT]
* @throws an error if UnicodeToNewBytes fails
*/
nsresult EncodeVal(const nsAString& aStr, nsACString& aResult);
/**
* Encode a Unicode string to bytes using an encoder. (Used by EncodeVal)
* @param aStr the string to encode
* @param aEncoder the encoder to encode the bytes with (cannot be null)
* @param aOut the encoded string [OUT]
* @throws an error if the encoder fails
*/
nsresult UnicodeToNewBytes(const nsAString& aStr, nsISaveAsCharset* aEncoder,
nsACString& aOut);
/** The name of the encoder charset */
nsCString mCharset;
/** The encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation)
*/
nsCOMPtr<nsISaveAsCharset> mEncoder;
/** A form processor who can listen to values */
nsCOMPtr<nsIFormProcessor> mFormProcessor;
/** The BIDI options flags for the current pres context */
PRInt32 mBidiOptions;
public:
// Static helpers
/**
* Get the submit charset for a form (suitable to pass in to the constructor).
* @param aForm the form in question
* @param aCtrlsModAtSubmit BIDI controls text mode. Unused in non-BIDI
* builds.
* @param aCharset the returned charset [OUT]
*/
static void GetSubmitCharset(nsGenericHTMLElement* aForm,
PRUint8 aCtrlsModAtSubmit,
nsACString& aCharset);
/**
* Get the encoder for a form (suitable to pass in to the constructor).
* @param aForm the form in question
* @param aCharset the charset of the form
* @param aEncoder the returned encoder [OUT]
*/
static nsresult GetEncoder(nsGenericHTMLElement* aForm,
const nsACString& aCharset,
nsISaveAsCharset** aEncoder);
/**
* Get an attribute of a form as int, provided that it is an enumerated value.
* @param aForm the form in question
* @param aAtom the attribute (for example, nsGkAtoms::enctype) to get
* @param aValue the result (will not be set at all if the attribute does not
* exist on the form, so *make sure you provide a default value*.)
* [OUT]
*/
static void GetEnumAttr(nsGenericHTMLElement* aForm,
nsIAtom* aAtom, PRInt32* aValue);
};
static void GetSubmitCharset(nsGenericHTMLElement* aForm,
PRUint8 aCtrlsModAtSubmit,
nsACString& aCharset);
/**
* Get the encoder for a form (suitable to pass in to the constructor).
* @param aForm the form in question
* @param aCharset the charset of the form
* @param aEncoder the returned encoder [OUT]
*/
static nsresult GetEncoder(nsGenericHTMLElement* aForm,
const nsACString& aCharset,
nsISaveAsCharset** aEncoder);
/**
* Get an attribute of a form as int, provided that it is an enumerated value.
* @param aForm the form in question
* @param aAtom the attribute (for example, nsGkAtoms::enctype) to get
* @param aValue the result (will not be set at all if the attribute does not
* exist on the form, so *make sure you provide a default value*.)
* [OUT]
*/
static void GetEnumAttr(nsGenericHTMLElement* aForm,
nsIAtom* aAtom, PRInt32* aValue);
//
// Static helper methods that don't really have nothing to do with nsFormSub
@ -215,34 +109,14 @@ public:
/**
* Send a warning to the JS console
* @param aContent the content the warning is about
* @param aWarningName the internationalized name of the warning within
* layout/html/forms/src/HtmlProperties.js
*/
static nsresult
SendJSWarning(nsIContent* aContent,
const char* aWarningName);
/**
* Send a warning to the JS console
* @param aContent the content the warning is about
* @param aWarningName the internationalized name of the warning within
* layout/html/forms/src/HtmlProperties.js
* @param aWarningArg1 an argument to replace a %S in the warning
*/
static nsresult
SendJSWarning(nsIContent* aContent,
const char* aWarningName,
const nsAFlatString& aWarningArg1);
/**
* Send a warning to the JS console
* @param aContent the content the warning is about
* @param aDocument the document the warning is about
* @param aWarningName the internationalized name of the warning within
* layout/html/forms/src/HtmlProperties.js
* @param aWarningArgs an array of strings to replace %S's in the warning
* @param aWarningArgsLen the number of strings in the array
*/
static nsresult
SendJSWarning(nsIContent* aContent,
static void
SendJSWarning(nsIDocument* aDocument,
const char* aWarningName,
const PRUnichar** aWarningArgs, PRUint32 aWarningArgsLen);
@ -254,40 +128,27 @@ public:
* @param aCharset the charset of the form as a string
* @param aEncoder an encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation)
* @param aFormProcessor a form processor who can listen to
* @param aBidiOptions the BIDI options flags for the current pres context
* @param aMethod the method of the submit (either NS_FORM_METHOD_GET or
* NS_FORM_METHOD_POST).
*/
nsFSURLEncoded(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions,
PRInt32 aMethod)
: nsFormSubmission(aCharset, aEncoder, aFormProcessor, aBidiOptions),
mMethod(aMethod)
{
}
virtual ~nsFSURLEncoded()
PRInt32 aMethod,
nsIDocument* aDocument)
: nsFormSubmission(aCharset, aEncoder, aBidiOptions),
mMethod(aMethod),
mDocument(aDocument),
mWarnedFileControl(PR_FALSE)
{
}
// nsIFormSubmission
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
// nsFormSubmission
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome);
virtual PRBool AcceptsFiles() const
{
return PR_FALSE;
}
NS_IMETHOD Init();
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
protected:
// nsFormSubmission
@ -315,43 +176,22 @@ private:
/** The query string so far (the part after the ?) */
nsCString mQueryString;
/** The document whose URI to use when reporting errors */
nsCOMPtr<nsIDocument> mDocument;
/** Whether or not we have warned about a file control not being submitted */
PRBool mWarnedFileControl;
};
nsresult
nsFSURLEncoded::AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
nsFSURLEncoded::AddNameValuePair(const nsAString& aName,
const nsAString& aValue)
{
//
// Check if there is an input type=file so that we can warn
//
if (!mWarnedFileControl) {
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aSource);
if (formControl->GetType() == NS_FORM_INPUT_FILE) {
nsCOMPtr<nsIContent> content = do_QueryInterface(aSource);
SendJSWarning(content, "ForgotFileEnctypeWarning");
mWarnedFileControl = PR_TRUE;
}
}
//
// Let external code process (and possibly change) value
//
nsAutoString processedValue;
nsresult rv = ProcessValue(aSource, aName, aValue, processedValue);
//
// Encode value
//
nsCString convValue;
if (NS_SUCCEEDED(rv)) {
rv = URLEncode(processedValue, convValue);
}
else {
rv = URLEncode(aValue, convValue);
}
nsresult rv = URLEncode(aValue, convValue);
NS_ENSURE_SUCCESS(rv, rv);
//
@ -376,25 +216,20 @@ nsFSURLEncoded::AddNameValuePair(nsIDOMHTMLElement* aSource,
}
nsresult
nsFSURLEncoded::AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome)
nsFSURLEncoded::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
{
return AddNameValuePair(aSource, aName, aFilename);
}
if (!mWarnedFileControl) {
SendJSWarning(mDocument, "ForgotFileEnctypeWarning", nsnull, 0);
mWarnedFileControl = PR_TRUE;
}
//
// nsFormSubmission
//
NS_IMETHODIMP
nsFSURLEncoded::Init()
{
mQueryString.Truncate();
mWarnedFileControl = PR_FALSE;
return NS_OK;
nsAutoString filename;
if (aFile) {
aFile->GetLeafName(filename);
}
return AddNameValuePair(aName, filename);
}
static void
@ -603,31 +438,17 @@ public:
* @param aCharset the charset of the form as a string
* @param aEncoder an encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation)
* @param aFormProcessor a form processor who can listen to
* @param aBidiOptions the BIDI options flags for the current pres context
*/
nsFSMultipartFormData(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions);
virtual ~nsFSMultipartFormData() { }
// nsIFormSubmission
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
// nsFormSubmission
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome);
virtual PRBool AcceptsFiles() const
{
return PR_TRUE;
}
NS_IMETHOD Init();
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
protected:
// nsFormSubmission
@ -639,34 +460,8 @@ protected:
* Roll up the data we have so far and add it to the multiplexed data stream.
*/
nsresult AddPostDataStream();
/**
* Call ProcessValue() and EncodeVal() on name and value.
*
* @param aSource the source of the name/value pair
* @param aName the name to be sent
* @param aValue the value to be sent
* @param aProcessedName the name, after being encoded [OUT]
* @param aProcessedValue the value, after being processed / encoded [OUT]
* @throws NS_ERROR_OUT_OF_MEMORY if out of memory
*/
nsresult ProcessAndEncode(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aValue,
nsCString& aProcessedName,
nsCString& aProcessedValue);
private:
/**
* Get whether we are supposed to be doing backwards compatible submit, which
* causes us to leave off the mandatory Content-Transfer-Encoding header.
* This used to cause Bad Things, including server crashes.
*
* It is hoped that we can get rid of this at some point, but that will take
* a lot of testing or some other browsers that send the header and have not
* had problems.
*/
PRBool mBackwardsCompatibleSubmit;
/**
* The post data stream as it is so far. This is a collection of smaller
* chunks--string streams and file streams interleaved to make one big POST
@ -696,66 +491,37 @@ private:
//
nsFSMultipartFormData::nsFSMultipartFormData(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions)
: nsFormSubmission(aCharset, aEncoder, aFormProcessor, aBidiOptions)
: nsFormSubmission(aCharset, aEncoder, aBidiOptions)
{
// XXX I can't *believe* we have a pref for this. ifdef, anyone?
mBackwardsCompatibleSubmit =
nsContentUtils::GetBoolPref("browser.forms.submit.backwards_compatible");
}
mPostDataStream =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
nsresult
nsFSMultipartFormData::ProcessAndEncode(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aValue,
nsCString& aProcessedName,
nsCString& aProcessedValue)
{
//
// Let external code process (and possibly change) value
//
nsAutoString processedValue;
nsresult rv = ProcessValue(aSource, aName, aValue, processedValue);
//
// Get value
//
nsCAutoString encodedVal;
if (NS_SUCCEEDED(rv)) {
rv = EncodeVal(processedValue, encodedVal);
} else {
rv = EncodeVal(aValue, encodedVal);
}
NS_ENSURE_SUCCESS(rv, rv);
//
// Get name
//
rv = EncodeVal(aName, aProcessedName);
NS_ENSURE_SUCCESS(rv, rv);
//
// Convert linebreaks in value
//
aProcessedValue.Adopt(nsLinebreakConverter::ConvertLineBreaks(encodedVal.get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
return NS_OK;
mBoundary.AssignLiteral("---------------------------");
mBoundary.AppendInt(rand());
mBoundary.AppendInt(rand());
mBoundary.AppendInt(rand());
}
//
// nsIFormSubmission
// nsFormSubmission
//
nsresult
nsFSMultipartFormData::AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
const nsAString& aValue)
{
nsCAutoString nameStr;
nsCString valueStr;
nsresult rv = ProcessAndEncode(aSource, aName, aValue, nameStr, valueStr);
nsCAutoString encodedVal;
nsresult rv = EncodeVal(aValue, encodedVal);
NS_ENSURE_SUCCESS(rv, rv);
valueStr.Adopt(nsLinebreakConverter::
ConvertLineBreaks(encodedVal.get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
nsCAutoString nameStr;
rv = EncodeVal(aName, nameStr);
NS_ENSURE_SUCCESS(rv, rv);
//
@ -774,29 +540,65 @@ nsFSMultipartFormData::AddNameValuePair(nsIDOMHTMLElement* aSource,
}
nsresult
nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome)
nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
{
// Encode the control name
nsCAutoString nameStr;
nsCAutoString filenameStr;
nsresult rv = ProcessAndEncode(aSource, aName, aFilename, nameStr, filenameStr);
nsresult rv = EncodeVal(aName, nameStr);
NS_ENSURE_SUCCESS(rv, rv);
nsCString filenameStr;
nsCAutoString contentType;
nsCOMPtr<nsIInputStream> fileStream;
if (aFile) {
// Get and encode the filename
nsAutoString filename;
aFile->GetLeafName(filename);
nsCAutoString encodedFileName;
rv = EncodeVal(filename, encodedFileName);
NS_ENSURE_SUCCESS(rv, rv);
filenameStr.Adopt(nsLinebreakConverter::
ConvertLineBreaks(encodedFileName.get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet));
// Get content type
nsCOMPtr<nsIMIMEService> MIMEService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = MIMEService->GetTypeFromFile(aFile, contentType);
if (NS_FAILED(rv)) {
contentType.AssignLiteral("application/octet-stream");
}
// Get input stream
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
aFile, -1, -1,
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND);
if (fileStream) {
// Create buffered stream (for efficiency)
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
fileStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
fileStream = bufferedStream;
}
}
else {
contentType.AssignLiteral("application/octet-stream");
}
//
// Make MIME block for name/value pair
//
// more appropriate than always using binary?
mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary
+ NS_LITERAL_CSTRING(CRLF);
if (!mBackwardsCompatibleSubmit) {
// XXX Is there any way to tell when "8bit" or "7bit" etc may be
mPostDataChunk +=
NS_LITERAL_CSTRING("Content-Transfer-Encoding: binary" CRLF);
}
// XXX: name/filename parameter should be encoded per RFC 2231
// RFC 2388 specifies that RFC 2047 be used, but I think it's not
// consistent with the MIME standard.
@ -804,18 +606,18 @@ nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource,
NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
+ nameStr + NS_LITERAL_CSTRING("\"; filename=\"")
+ filenameStr + NS_LITERAL_CSTRING("\"" CRLF)
+ NS_LITERAL_CSTRING("Content-Type: ") + aContentType
+ NS_LITERAL_CSTRING("Content-Type: ") + contentType
+ NS_LITERAL_CSTRING(CRLF CRLF);
//
// Add the file to the stream
//
if (aStream) {
if (fileStream) {
// We need to dump the data up to this point into the POST data stream here,
// since we're about to add the file input stream
AddPostDataStream();
mPostDataStream->AppendStream(aStream);
mPostDataStream->AppendStream(fileStream);
}
//
@ -826,35 +628,6 @@ nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource,
return NS_OK;
}
//
// nsFormSubmission
//
NS_IMETHODIMP
nsFSMultipartFormData::Init()
{
nsresult rv;
//
// Create the POST stream
//
mPostDataStream =
do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (!mPostDataStream) {
return NS_ERROR_OUT_OF_MEMORY;
}
//
// Build boundary
//
mBoundary.AssignLiteral("---------------------------");
mBoundary.AppendInt(rand());
mBoundary.AppendInt(rand());
mBoundary.AppendInt(rand());
return NS_OK;
}
NS_IMETHODIMP
nsFSMultipartFormData::GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream)
@ -920,86 +693,49 @@ class nsFSTextPlain : public nsFormSubmission
public:
nsFSTextPlain(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions)
: nsFormSubmission(aCharset, aEncoder, aFormProcessor, aBidiOptions)
{
}
virtual ~nsFSTextPlain()
: nsFormSubmission(aCharset, aEncoder, aBidiOptions)
{
}
// nsIFormSubmission
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
// nsFormSubmission
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue);
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome);
NS_IMETHOD Init();
virtual nsresult AddNameFilePair(const nsAString& aName,
nsIFile* aFile);
protected:
// nsFormSubmission
NS_IMETHOD GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream);
virtual PRBool AcceptsFiles() const
{
return PR_FALSE;
}
private:
nsString mBody;
};
nsresult
nsFSTextPlain::AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
nsFSTextPlain::AddNameValuePair(const nsAString& aName,
const nsAString& aValue)
{
//
// Let external code process (and possibly change) value
//
nsString processedValue;
nsresult rv = ProcessValue(aSource, aName, aValue, processedValue);
// XXX This won't work well with a name like "a=b" or "a\nb" but I suppose
// text/plain doesn't care about that. Parsers aren't built for escaped
// values so we'll have to live with it.
if (NS_SUCCEEDED(rv)) {
mBody.Append(aName + NS_LITERAL_STRING("=") + processedValue +
NS_LITERAL_STRING(CRLF));
} else {
mBody.Append(aName + NS_LITERAL_STRING("=") + aValue +
NS_LITERAL_STRING(CRLF));
}
mBody.Append(aName + NS_LITERAL_STRING("=") + aValue +
NS_LITERAL_STRING(CRLF));
return NS_OK;
}
nsresult
nsFSTextPlain::AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome)
nsFSTextPlain::AddNameFilePair(const nsAString& aName,
nsIFile* aFile)
{
AddNameValuePair(aSource,aName,aFilename);
return NS_OK;
}
nsAutoString filename;
if (aFile) {
aFile->GetLeafName(filename);
}
//
// nsFormSubmission
//
NS_IMETHODIMP
nsFSTextPlain::Init()
{
mBody.Truncate();
AddNameValuePair(aName, filename);
return NS_OK;
}
@ -1033,7 +769,6 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
rv = aURI->SetPath(path);
} else {
// Create data stream
nsCOMPtr<nsIInputStream> bodyStream;
rv = NS_NewStringInputStream(getter_AddRefs(bodyStream),
@ -1056,65 +791,49 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
return rv;
}
//
// CLASS nsFormSubmission
//
//
// nsISupports stuff
//
NS_IMPL_ISUPPORTS1(nsFormSubmission, nsIFormSubmission)
// JBK moved from nsFormFrame - bug 34297
// submission
static nsresult
SendJSWarning(nsIContent* aContent,
const char* aWarningName)
nsFormSubmission::nsFormSubmission(const nsACString& aCharset,
nsISaveAsCharset* aEncoder,
PRInt32 aBidiOptions)
: mCharset(aCharset),
mEncoder(aEncoder),
mBidiOptions(aBidiOptions)
{
return SendJSWarning(aContent, aWarningName, nsnull, 0);
}
static nsresult
SendJSWarning(nsIContent* aContent,
const char* aWarningName,
const nsAFlatString& aWarningArg1)
nsFormSubmission::~nsFormSubmission()
{
const PRUnichar* formatStrings[1] = { aWarningArg1.get() };
return SendJSWarning(aContent, aWarningName, formatStrings, 1);
}
static nsresult
SendJSWarning(nsIContent* aContent,
void
nsFormSubmission::Release()
{
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsFormSubmission");
if (mRefCnt == 0) {
mRefCnt = 1; // stabilize
delete this;
}
}
static void
SendJSWarning(nsIDocument* aDocument,
const char* aWarningName,
const PRUnichar** aWarningArgs, PRUint32 aWarningArgsLen)
{
// Get the document URL to use as the filename
nsIDocument* document = aContent->GetDocument();
nsIURI *documentURI = nsnull;
if (document) {
documentURI = document->GetDocumentURI();
NS_ENSURE_TRUE(documentURI, NS_ERROR_UNEXPECTED);
}
return nsContentUtils::ReportToConsole(nsContentUtils::eFORMS_PROPERTIES,
aWarningName,
aWarningArgs, aWarningArgsLen,
documentURI,
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"HTML");
nsContentUtils::ReportToConsole(nsContentUtils::eFORMS_PROPERTIES,
aWarningName,
aWarningArgs, aWarningArgsLen,
aDocument ? aDocument->GetDocumentURI() :
nsnull,
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"HTML");
}
nsresult
GetSubmissionFromForm(nsGenericHTMLElement* aForm,
nsIFormSubmission** aFormSubmission)
nsFormSubmission** aFormSubmission)
{
nsresult rv = NS_OK;
//
// Get all the information necessary to encode the form data
//
@ -1128,23 +847,19 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
// Get encoding type (default: urlencoded)
PRInt32 enctype = NS_FORM_ENCTYPE_URLENCODED;
nsFormSubmission::GetEnumAttr(aForm, nsGkAtoms::enctype, &enctype);
GetEnumAttr(aForm, nsGkAtoms::enctype, &enctype);
// Get method (default: GET)
PRInt32 method = NS_FORM_METHOD_GET;
nsFormSubmission::GetEnumAttr(aForm, nsGkAtoms::method, &method);
GetEnumAttr(aForm, nsGkAtoms::method, &method);
// Get charset
nsCAutoString charset;
nsFormSubmission::GetSubmitCharset(aForm, ctrlsModAtSubmit, charset);
GetSubmitCharset(aForm, ctrlsModAtSubmit, charset);
// Get unicode encoder
nsCOMPtr<nsISaveAsCharset> encoder;
nsFormSubmission::GetEncoder(aForm, charset, getter_AddRefs(encoder));
// Get form processor
nsCOMPtr<nsIFormProcessor> formProcessor =
do_GetService(kFormProcessorCID, &rv);
GetEncoder(aForm, charset, getter_AddRefs(encoder));
//
// Choose encoder
@ -1157,29 +872,25 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_MULTIPART) {
*aFormSubmission = new nsFSMultipartFormData(charset, encoder,
formProcessor, bidiOptions);
bidiOptions);
} else if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
*aFormSubmission = new nsFSTextPlain(charset, encoder,
formProcessor, bidiOptions);
*aFormSubmission = new nsFSTextPlain(charset, encoder, bidiOptions);
} else {
if (enctype == NS_FORM_ENCTYPE_MULTIPART ||
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
nsAutoString enctypeStr;
aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::enctype, enctypeStr);
SendJSWarning(aForm, "ForgotPostWarning", PromiseFlatString(enctypeStr));
const PRUnichar* enctypeStrPtr = enctypeStr.get();
SendJSWarning(aForm->GetOwnerDoc(), "ForgotPostWarning",
&enctypeStrPtr, 1);
}
*aFormSubmission = new nsFSURLEncoded(charset, encoder,
formProcessor, bidiOptions, method);
*aFormSubmission = new nsFSURLEncoded(charset, encoder, bidiOptions,
method, aForm->GetOwnerDoc());
}
NS_ENSURE_TRUE(*aFormSubmission, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aFormSubmission);
// This ASSUMES that all encodings above inherit from nsFormSubmission, which
// they currently do. If that changes, change this too.
static_cast<nsFormSubmission*>(*aFormSubmission)->Init();
return NS_OK;
}
@ -1208,12 +919,10 @@ nsFormSubmission::SubmitTo(nsIURI* aActionURI, const nsAString& aTarget,
aDocShell, aRequest);
}
// JBK moved from nsFormFrame - bug 34297
// static
void
nsFormSubmission::GetSubmitCharset(nsGenericHTMLElement* aForm,
PRUint8 aCtrlsModAtSubmit,
nsACString& oCharset)
GetSubmitCharset(nsGenericHTMLElement* aForm,
PRUint8 aCtrlsModAtSubmit,
nsACString& oCharset)
{
oCharset.AssignLiteral("UTF-8"); // default to utf-8
@ -1279,12 +988,10 @@ nsFormSubmission::GetSubmitCharset(nsGenericHTMLElement* aForm,
}
// JBK moved from nsFormFrame - bug 34297
// static
nsresult
nsFormSubmission::GetEncoder(nsGenericHTMLElement* aForm,
const nsACString& aCharset,
nsISaveAsCharset** aEncoder)
GetEncoder(nsGenericHTMLElement* aForm,
const nsACString& aCharset,
nsISaveAsCharset** aEncoder)
{
*aEncoder = nsnull;
nsresult rv = NS_OK;
@ -1385,8 +1092,8 @@ nsFormSubmission::UnicodeToNewBytes(const nsAString& aStr,
// static
void
nsFormSubmission::GetEnumAttr(nsGenericHTMLElement* aContent,
nsIAtom* atom, PRInt32* aValue)
GetEnumAttr(nsGenericHTMLElement* aContent,
nsIAtom* atom, PRInt32* aValue)
{
const nsAttrValue* value = aContent->GetParsedAttr(atom);
if (value && value->Type() == nsAttrValue::eEnum) {
@ -1405,27 +1112,3 @@ nsFormSubmission::EncodeVal(const nsAString& aStr, nsACString& aOut)
CopyUTF16toUTF8(aStr, aOut);
return NS_OK;
}
nsresult
nsFormSubmission::ProcessValue(nsIDOMHTMLElement* aSource,
const nsAString& aName, const nsAString& aValue,
nsAString& aResult)
{
// Hijack _charset_ (hidden inputs only) for internationalization (bug 18643)
if (aName.EqualsLiteral("_charset_")) {
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aSource);
if (formControl && formControl->GetType() == NS_FORM_INPUT_HIDDEN) {
CopyASCIItoUTF16(mCharset, aResult);
return NS_OK;
}
}
nsresult rv = NS_OK;
aResult = aValue;
if (mFormProcessor) {
rv = mFormProcessor->ProcessValue(aSource, aName, aResult);
NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to Notify form process observer");
}
return rv;
}

View File

@ -100,7 +100,7 @@ public:
// overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return mType; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD SaveState();
PRBool RestoreState(nsPresState* aState);
@ -503,7 +503,7 @@ nsHTMLButtonElement::Reset()
}
NS_IMETHODIMP
nsHTMLButtonElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLButtonElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
nsresult rv = NS_OK;
@ -545,7 +545,7 @@ nsHTMLButtonElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
//
// Submit
//
rv = aFormSubmission->AddNameValuePair(this, name, value);
rv = aFormSubmission->AddNameValuePair(name, value);
return rv;
}

View File

@ -69,7 +69,7 @@ public:
// nsIFormControl
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_FIELDSET; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
};
@ -127,7 +127,7 @@ nsHTMLFieldSetElement::Reset()
}
NS_IMETHODIMP
nsHTMLFieldSetElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLFieldSetElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
return NS_OK;

View File

@ -709,7 +709,7 @@ nsHTMLFormElement::DoSubmit(nsEvent* aEvent)
mIsSubmitting = PR_TRUE;
NS_ASSERTION(!mWebProgress && !mSubmittingRequest, "Web progress / submitting request should not exist here!");
nsCOMPtr<nsIFormSubmission> submission;
nsRefPtr<nsFormSubmission> submission;
//
// prepare the submission object
@ -745,7 +745,7 @@ nsHTMLFormElement::DoSubmit(nsEvent* aEvent)
}
nsresult
nsHTMLFormElement::BuildSubmission(nsCOMPtr<nsIFormSubmission>& aFormSubmission,
nsHTMLFormElement::BuildSubmission(nsRefPtr<nsFormSubmission>& aFormSubmission,
nsEvent* aEvent)
{
NS_ASSERTION(!mPendingSubmission, "tried to build two submissions!");
@ -776,7 +776,7 @@ nsHTMLFormElement::BuildSubmission(nsCOMPtr<nsIFormSubmission>& aFormSubmission,
}
nsresult
nsHTMLFormElement::SubmitSubmission(nsIFormSubmission* aFormSubmission)
nsHTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission)
{
nsresult rv;
//
@ -947,7 +947,7 @@ nsHTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL,
nsresult
nsHTMLFormElement::WalkFormElements(nsIFormSubmission* aFormSubmission,
nsHTMLFormElement::WalkFormElements(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
nsTArray<nsGenericHTMLFormElement*> sortedControls;
@ -1327,7 +1327,7 @@ nsHTMLFormElement::OnSubmitClickEnd()
void
nsHTMLFormElement::FlushPendingSubmission()
{
nsCOMPtr<nsIFormSubmission> kunkFuDeathGrip(mPendingSubmission);
nsRefPtr<nsFormSubmission> kunkFuDeathGrip(mPendingSubmission);
if (!mPendingSubmission) {
return;

View File

@ -289,14 +289,14 @@ protected:
* @param aFormSubmission the submission object
* @param aEvent the DOM event that was passed to us for the submit
*/
nsresult BuildSubmission(nsCOMPtr<nsIFormSubmission>& aFormSubmission,
nsresult BuildSubmission(nsRefPtr<nsFormSubmission>& aFormSubmission,
nsEvent* aEvent);
/**
* Perform the submission (called by DoSubmit and FlushPendingSubmission)
*
* @param aFormSubmission the submission object
*/
nsresult SubmitSubmission(nsIFormSubmission* aFormSubmission);
nsresult SubmitSubmission(nsFormSubmission* aFormSubmission);
/**
* Walk over the form elements and call SubmitNamesValues() on them to get
* their data pumped into the FormSubmitter.
@ -304,7 +304,7 @@ protected:
* @param aFormSubmission the form submission object
* @param aSubmitElement the element that was clicked on (nsnull if none)
*/
nsresult WalkFormElements(nsIFormSubmission* aFormSubmission,
nsresult WalkFormElements(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
/**
@ -371,7 +371,7 @@ protected:
PRBool mSubmitInitiatedFromUserInput;
/** The pending submission object */
nsCOMPtr<nsIFormSubmission> mPendingSubmission;
nsRefPtr<nsFormSubmission> mPendingSubmission;
/** The request currently being submitted */
nsCOMPtr<nsIRequest> mSubmittingRequest;
/** The web progress object we are currently listening to */

View File

@ -98,11 +98,8 @@
#include "nsIRadioGroupContainer.h"
// input type=file
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
#include "nsIFile.h"
#include "nsILocalFile.h"
#include "nsIFileStreams.h"
#include "nsNetUtil.h"
#include "nsDOMFile.h"
@ -258,7 +255,7 @@ public:
// Overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return mType; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD SaveState();
virtual PRBool RestoreState(nsPresState* aState);
@ -407,6 +404,14 @@ protected:
*/
nsresult SetCheckedInternal(PRBool aValue, PRBool aNotify);
/**
* Syntax sugar to make it easier to check for checked
*/
PRBool GetChecked() const
{
return GET_BOOLBIT(mBitField, BF_CHECKED);
}
/**
* MaybeSubmitForm looks for a submit input or a single text control
* and submits the form if either is present.
@ -548,10 +553,7 @@ nsHTMLInputElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
if (GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED)) {
// We no longer have our original checked state. Set our
// checked state on the clone.
// XXX GetChecked should be const
PRBool checked;
const_cast<nsHTMLInputElement*>(this)->GetChecked(&checked);
it->DoSetChecked(checked, PR_FALSE);
it->DoSetChecked(GetChecked(), PR_FALSE);
}
break;
case NS_FORM_INPUT_IMAGE:
@ -1159,7 +1161,7 @@ nsHTMLInputElement::SetValueChanged(PRBool aValueChanged)
NS_IMETHODIMP
nsHTMLInputElement::GetChecked(PRBool* aChecked)
{
*aChecked = GET_BOOLBIT(mBitField, BF_CHECKED);
*aChecked = GetChecked();
return NS_OK;
}
@ -1224,9 +1226,7 @@ nsHTMLInputElement::DoSetChecked(PRBool aChecked, PRBool aNotify)
// screw up state actually, especially when you are setting radio button to
// false)
//
PRBool checked = PR_FALSE;
GetChecked(&checked);
if (checked == aChecked) {
if (GetChecked() == aChecked) {
return NS_OK;
}
@ -1652,7 +1652,7 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
}
}
GetChecked(&originalCheckedValue);
originalCheckedValue = GetChecked();
if (!originalCheckedValue) {
DoSetChecked(PR_TRUE);
SET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED, PR_TRUE);
@ -2552,56 +2552,32 @@ nsHTMLInputElement::Reset()
}
NS_IMETHODIMP
nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
nsresult rv = NS_OK;
//
// Disabled elements don't submit
//
PRBool disabled;
rv = GetDisabled(&disabled);
if (NS_FAILED(rv) || disabled) {
return rv;
}
//
// For type=reset, and type=button, we just never submit, period.
//
if (mType == NS_FORM_INPUT_RESET || mType == NS_FORM_INPUT_BUTTON) {
return rv;
}
//
// For type=image and type=button, we only submit if we were the button
// pressed
//
if ((mType == NS_FORM_INPUT_SUBMIT || mType == NS_FORM_INPUT_IMAGE)
&& aSubmitElement != this) {
return rv;
}
//
// For type=radio and type=checkbox, we only submit if checked=true
//
if (mType == NS_FORM_INPUT_RADIO || mType == NS_FORM_INPUT_CHECKBOX) {
PRBool checked;
rv = GetChecked(&checked);
if (NS_FAILED(rv) || !checked) {
return rv;
}
PRBool disabled;
rv = GetDisabled(&disabled);
if (disabled || mType == NS_FORM_INPUT_RESET ||
mType == NS_FORM_INPUT_BUTTON ||
((mType == NS_FORM_INPUT_SUBMIT || mType == NS_FORM_INPUT_IMAGE) &&
aSubmitElement != this) ||
((mType == NS_FORM_INPUT_RADIO || mType == NS_FORM_INPUT_CHECKBOX) &&
!GetChecked())) {
return NS_OK;
}
//
// Get the name
//
nsAutoString name;
PRBool nameThere = GetNameIfExists(name);
//
// Submit .x, .y for input type=image
//
if (mType == NS_FORM_INPUT_IMAGE) {
// Get a property set by the frame to find out where it was clicked.
nsIntPoint* lastClickedPoint =
@ -2620,15 +2596,13 @@ nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
yVal.AppendInt(y);
if (!name.IsEmpty()) {
aFormSubmission->AddNameValuePair(this,
name + NS_LITERAL_STRING(".x"), xVal);
aFormSubmission->AddNameValuePair(this,
name + NS_LITERAL_STRING(".y"), yVal);
aFormSubmission->AddNameValuePair(name + NS_LITERAL_STRING(".x"), xVal);
aFormSubmission->AddNameValuePair(name + NS_LITERAL_STRING(".y"), yVal);
} else {
// If the Image Element has no name, simply return x and y
// to Nav and IE compatibility.
aFormSubmission->AddNameValuePair(this, NS_LITERAL_STRING("x"), xVal);
aFormSubmission->AddNameValuePair(this, NS_LITERAL_STRING("y"), yVal);
aFormSubmission->AddNameValuePair(NS_LITERAL_STRING("x"), xVal);
aFormSubmission->AddNameValuePair(NS_LITERAL_STRING("y"), yVal);
}
return NS_OK;
@ -2640,7 +2614,7 @@ nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
// If name not there, don't submit
if (!nameThere) {
return rv;
return NS_OK;
}
// Get the value
@ -2665,68 +2639,17 @@ nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
if (mType == NS_FORM_INPUT_FILE) {
// Submit files
nsCOMPtr<nsIMIMEService> MIMEService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMArray<nsIFile> files;
GetFileArray(files);
for (PRUint32 i = 0; i < (PRUint32)files.Count(); ++i) {
nsIFile* file = files[i];
// Get the leaf path name (to be submitted as the value)
PRBool fileSent = PR_FALSE;
nsAutoString filename;
rv = file->GetLeafName(filename);
if (NS_FAILED(rv)) {
filename.Truncate();
}
if (!filename.IsEmpty() && aFormSubmission->AcceptsFiles()) {
// Get content type
nsCAutoString contentType;
rv = MIMEService->GetTypeFromFile(file, contentType);
if (NS_FAILED(rv)) {
contentType.AssignLiteral("application/octet-stream");
}
// Get input stream
nsCOMPtr<nsIInputStream> fileStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
file, -1, -1,
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND);
if (fileStream) {
// Create buffered stream (for efficiency)
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
fileStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
// Submit
aFormSubmission->AddNameFilePair(this, name, filename,
bufferedStream, contentType,
PR_FALSE);
fileSent = PR_TRUE;
}
}
if (!fileSent) {
// If we don't submit as a file, at least submit the truncated filename.
aFormSubmission->AddNameFilePair(this, name, filename,
nsnull, NS_LITERAL_CSTRING("application/octet-stream"),
PR_FALSE);
}
aFormSubmission->AddNameFilePair(name, files[i]);
}
if (files.Count() == 0) {
// If no file was selected, pretend we had an empty file with an
// empty filename.
aFormSubmission->AddNameFilePair(this, name, EmptyString(), nsnull,
NS_LITERAL_CSTRING("application/octet-stream"),
PR_FALSE);
aFormSubmission->AddNameFilePair(name, nsnull);
}
@ -2735,8 +2658,14 @@ nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
// Submit
// (for type=image, only submit if value is non-null)
if (mType != NS_FORM_INPUT_IMAGE || !value.IsEmpty()) {
rv = aFormSubmission->AddNameValuePair(this, name, value);
if (mType == NS_FORM_INPUT_HIDDEN && name.EqualsLiteral("_charset_")) {
nsCString charset;
aFormSubmission->GetCharset(charset);
rv = aFormSubmission->AddNameValuePair(name,
NS_ConvertASCIItoUTF16(charset));
}
else if (mType != NS_FORM_INPUT_IMAGE || !value.IsEmpty()) {
rv = aFormSubmission->AddNameValuePair(name, value);
}
return rv;
@ -2754,8 +2683,7 @@ nsHTMLInputElement::SaveState()
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
{
PRBool checked = PR_FALSE;
GetChecked(&checked);
PRBool checked = GetChecked();
PRBool defaultChecked = PR_FALSE;
GetDefaultChecked(&defaultChecked);
// Only save if checked != defaultChecked (bug 62713)
@ -2959,9 +2887,7 @@ nsHTMLInputElement::AddedToRadioGroup(PRBool aNotify)
// If the input element is checked, and we add it to the group, it will
// deselect whatever is currently selected in that group
//
PRBool checked;
GetChecked(&checked);
if (checked) {
if (GetChecked()) {
//
// If it is checked, call "RadioSetChecked" to perform the selection/
// deselection ritual. This has the side effect of repainting the
@ -3014,12 +2940,9 @@ nsHTMLInputElement::WillRemoveFromRadioGroup()
// If this button was checked, we need to notify the group that there is no
// longer a selected radio button
//
PRBool checked = PR_FALSE;
GetChecked(&checked);
nsAutoString name;
PRBool gotName = PR_FALSE;
if (checked) {
if (GetChecked()) {
if (!gotName) {
if (!GetNameIfExists(name)) {
// If the name doesn't exist, nothing is going to happen anyway
@ -3103,9 +3026,7 @@ nsHTMLInputElement::IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex)
return PR_FALSE;
}
PRBool checked;
GetChecked(&checked);
if (checked) {
if (GetChecked()) {
// Selected radio buttons are tabbable
*aIsFocusable = PR_TRUE;
return PR_FALSE;

View File

@ -78,7 +78,7 @@ public:
// nsIFormControl
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_LABEL; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD Focus();
@ -329,7 +329,7 @@ nsHTMLLabelElement::Reset()
}
NS_IMETHODIMP
nsHTMLLabelElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
return NS_OK;

View File

@ -75,7 +75,7 @@ public:
// nsIFormControl
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_LEGEND; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHODIMP Focus();
@ -284,7 +284,7 @@ nsHTMLLegendElement::PerformAccesskey(PRBool aKeyCausesActivation,
}
NS_IMETHODIMP
nsHTMLLegendElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLLegendElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
return NS_OK;

View File

@ -103,7 +103,7 @@ public:
}
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission *aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission *aFormSubmission,
nsIContent *aSubmitElement);
virtual nsresult DoneAddingChildren(PRBool aHaveNotified);
@ -316,7 +316,7 @@ nsHTMLObjectElement::Reset()
}
NS_IMETHODIMP
nsHTMLObjectElement::SubmitNamesValues(nsIFormSubmission *aFormSubmission,
nsHTMLObjectElement::SubmitNamesValues(nsFormSubmission *aFormSubmission,
nsIContent *aSubmitElement)
{
nsAutoString name;
@ -344,7 +344,7 @@ nsHTMLObjectElement::SubmitNamesValues(nsIFormSubmission *aFormSubmission,
nsresult rv = pi->GetFormValue(value);
NS_ENSURE_SUCCESS(rv, rv);
return aFormSubmission->AddNameValuePair(this, name, value);
return aFormSubmission->AddNameValuePair(name, value);
}
NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Align, align)

View File

@ -47,6 +47,7 @@
#include "nsMappedAttributes.h"
#include "nsIForm.h"
#include "nsIFormSubmission.h"
#include "nsIFormProcessor.h"
#include "nsIDOMHTMLOptGroupElement.h"
#include "nsIOptionElement.h"
@ -66,6 +67,7 @@
#include "nsIFrame.h"
#include "nsDOMError.h"
#include "nsServiceManagerUtils.h"
#include "nsRuleData.h"
#include "nsEventDispatcher.h"
@ -1582,8 +1584,10 @@ nsHTMLSelectElement::Reset()
return NS_OK;
}
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
NS_IMETHODIMP
nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLSelectElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
nsresult rv = NS_OK;
@ -1612,6 +1616,13 @@ nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
PRUint32 len;
GetLength(&len);
nsAutoString mozType;
nsCOMPtr<nsIFormProcessor> keyGenProcessor;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::_moz_type, mozType) &&
mozType.EqualsLiteral("-mozilla-keygen")) {
keyGenProcessor = do_GetService(kFormProcessorCID, &rv);
}
for (PRUint32 optIndex = 0; optIndex < len; optIndex++) {
// Don't send disabled options
PRBool disabled;
@ -1637,7 +1648,15 @@ nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
rv = optionElement->GetValue(value);
NS_ENSURE_SUCCESS(rv, rv);
rv = aFormSubmission->AddNameValuePair(this, name, value);
if (keyGenProcessor) {
nsAutoString tmp(value);
rv = keyGenProcessor->ProcessValue(this, name, tmp);
if (NS_SUCCEEDED(rv)) {
value = tmp;
}
}
rv = aFormSubmission->AddNameValuePair(name, value);
}
return NS_OK;

View File

@ -276,7 +276,7 @@ public:
// Overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_SELECT; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD SaveState();
virtual PRBool RestoreState(nsPresState* aState);

View File

@ -121,7 +121,7 @@ public:
// nsIFormControl
NS_IMETHOD_(PRInt32) GetType() const { return NS_FORM_TEXTAREA; }
NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD SaveState();
virtual PRBool RestoreState(nsPresState* aState);
@ -812,7 +812,7 @@ nsHTMLTextAreaElement::Reset()
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsHTMLTextAreaElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
nsresult rv = NS_OK;
@ -843,7 +843,7 @@ nsHTMLTextAreaElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
//
// Submit
//
rv = aFormSubmission->AddNameValuePair(this, name, value);
rv = aFormSubmission->AddNameValuePair(name, value);
return rv;
}

View File

@ -219,9 +219,6 @@ pref("gfx.use_text_smoothing_setting", false);
// loading and rendering of framesets and iframes
pref("browser.frames.enabled", true);
// form submission
pref("browser.forms.submit.backwards_compatible", true);
// Number of characters to consider emphasizing for rich autocomplete results
pref("toolkit.autocomplete.richBoundaryCutoff", 200);

View File

@ -803,43 +803,31 @@ nsKeygenFormProcessor::ProcessValue(nsIDOMHTMLElement *aElement,
const nsAString& aName,
nsAString& aValue)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIDOMHTMLSelectElement>selectElement;
nsresult res = aElement->QueryInterface(kIDOMHTMLSelectElementIID,
getter_AddRefs(selectElement));
if (NS_SUCCEEDED(res)) {
nsAutoString keygenvalue;
nsAutoString challengeValue;
nsAutoString keyTypeValue;
nsAutoString keyParamsValue;
selectElement->GetAttribute(NS_LITERAL_STRING("_moz-type"), keygenvalue);
if (keygenvalue.EqualsLiteral("-mozilla-keygen")) {
res = selectElement->GetAttribute(NS_LITERAL_STRING("keytype"), keyTypeValue);
if (NS_FAILED(res) || keyTypeValue.IsEmpty()) {
aElement->GetAttribute(NS_LITERAL_STRING("keytype"), keyTypeValue);
if (keyTypeValue.IsEmpty()) {
// If this field is not present, we default to rsa.
keyTypeValue.AssignLiteral("rsa");
}
res = selectElement->GetAttribute(NS_LITERAL_STRING("pqg"),
keyParamsValue);
/* XXX We can still support the pqg attribute in the keygen
* tag for backward compatibility while introducing a more
* general attribute named keyparams.
*/
if (NS_FAILED(res) || keyParamsValue.IsEmpty()) {
res = selectElement->GetAttribute(NS_LITERAL_STRING("keyparams"),
keyParamsValue);
}
res = selectElement->GetAttribute(NS_LITERAL_STRING("challenge"), challengeValue);
rv = GetPublicKey(aValue, challengeValue, keyTypeValue,
aValue, keyParamsValue);
keyTypeValue.AssignLiteral("rsa");
}
}
return rv;
aElement->GetAttribute(NS_LITERAL_STRING("pqg"),
keyParamsValue);
/* XXX We can still support the pqg attribute in the keygen
* tag for backward compatibility while introducing a more
* general attribute named keyparams.
*/
if (keyParamsValue.IsEmpty()) {
aElement->GetAttribute(NS_LITERAL_STRING("keyparams"),
keyParamsValue);
}
aElement->GetAttribute(NS_LITERAL_STRING("challenge"), challengeValue);
return GetPublicKey(aValue, challengeValue, keyTypeValue,
aValue, keyParamsValue);
}
NS_METHOD nsKeygenFormProcessor::ProvideContent(const nsAString& aFormType,