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(mozgeneratedcontentafter, "_moz_generated_content_after")
GK_ATOM(mozgeneratedcontentimage, "_moz_generated_content_image") GK_ATOM(mozgeneratedcontentimage, "_moz_generated_content_image")
GK_ATOM(_moz_target, "_moz_target") GK_ATOM(_moz_target, "_moz_target")
GK_ATOM(_moz_type, "_moz-type")
GK_ATOM(menuactive, "_moz-menuactive") GK_ATOM(menuactive, "_moz-menuactive")
GK_ATOM(_poundDefault, "#default") GK_ATOM(_poundDefault, "#default")
GK_ATOM(_asterix, "*") GK_ATOM(_asterix, "*")

View File

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

View File

@ -38,8 +38,9 @@
#define nsIFormSubmission_h___ #define nsIFormSubmission_h___
#include "nsISupports.h" #include "nsISupports.h"
class nsAString; #include "nsString.h"
class nsACString; #include "nsCOMPtr.h"
class nsIURI; class nsIURI;
class nsIInputStream; class nsIInputStream;
class nsGenericHTMLElement; class nsGenericHTMLElement;
@ -49,27 +50,23 @@ class nsIFormControl;
class nsIDOMHTMLElement; class nsIDOMHTMLElement;
class nsIDocShell; class nsIDocShell;
class nsIRequest; class nsIRequest;
class nsISaveAsCharset;
#define NS_IFORMSUBMISSION_IID \
{ 0x7ee38e3a, 0x1dd2, 0x11b2, \
{0x89, 0x6f, 0xab, 0x28, 0x03, 0x96, 0x25, 0xa9} }
/** /**
* 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 * well as the form submission name/value pairs
*/ */
class nsIFormSubmission : public nsISupports class nsFormSubmission {
{
public: public:
virtual ~nsFormSubmission();
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFORMSUBMISSION_IID) void AddRef()
{
/** ++mRefCnt;
* Find out whether or not this form submission accepts files NS_LOG_ADDREF(this, mRefCnt, "nsFormSubmission", sizeof(*this));
* }
* @param aAcceptsFiles the boolean output void Release();
*/
virtual PRBool AcceptsFiles() const = 0;
/** /**
* Call to perform the submission * Call to perform the submission
@ -82,47 +79,87 @@ public:
* loaded * loaded
* @param aRequest (out param) the Request for the submission * @param aRequest (out param) the Request for the submission
*/ */
virtual nsresult SubmitTo(nsIURI* aActionURL, const nsAString& aTarget, nsresult SubmitTo(nsIURI* aActionURI, const nsAString& aTarget,
nsIContent* aSource, nsILinkHandler* aLinkHandler, nsIContent* aSource, nsILinkHandler* aLinkHandler,
nsIDocShell** aDocShell, nsIDocShell** aDocShell, nsIRequest** aRequest);
nsIRequest** aRequest) = 0;
/** /**
* Submit a name/value pair * Submit a name/value pair
* *
* @param aSource the control sending the parameter
* @param aName the name of the parameter * @param aName the name of the parameter
* @param aValue the value of the parameter * @param aValue the value of the parameter
*/ */
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue) = 0; const nsAString& aValue) = 0;
/** /**
* Submit a name/file pair * Submit a name/file pair
* *
* @param aSource the control sending the parameter
* @param aName the name of the parameter * @param aName the name of the parameter
* @param aFilename the name of the file (pass null to provide no name) * @param aFile the file to submit
* @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
*/ */
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile) = 0;
const nsAString& aFilename,
nsIInputStream* aStream, /**
const nsACString& aContentType, * Get the charset that will be used for submission.
PRBool aMoreFilesToCome) = 0; */
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) * 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) * @param aFormSubmission the form submission object (out param)
*/ */
nsresult GetSubmissionFromForm(nsGenericHTMLElement* aForm, nsresult GetSubmissionFromForm(nsGenericHTMLElement* aForm,
nsIFormSubmission** aFormSubmission); nsFormSubmission** aFormSubmission);
#endif /* nsIFormSubmission_h___ */ #endif /* nsIFormSubmission_h___ */

View File

@ -55,7 +55,6 @@
#include "nsIFile.h" #include "nsIFile.h"
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
#include "nsStringStream.h" #include "nsStringStream.h"
#include "nsIFormProcessor.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
@ -66,148 +65,43 @@
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsIMultiplexInputStream.h" #include "nsIMultiplexInputStream.h"
#include "nsIMIMEInputStream.h" #include "nsIMIMEInputStream.h"
#include "nsIMIMEService.h"
#include "nsIConsoleService.h" #include "nsIConsoleService.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "nsIStringBundle.h" #include "nsIStringBundle.h"
#include "nsCExternalHandlerService.h"
//BIDI #include "nsIFileStreams.h"
#include "nsBidiUtils.h" #include "nsBidiUtils.h"
//end
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
/** /**
* Helper superclass implementation of nsIFormSubmission, providing common * Get the submit charset for a form (suitable to pass in to the constructor).
* methods that most of the specific implementations need and use. * @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 { static void GetSubmitCharset(nsGenericHTMLElement* aForm,
PRUint8 aCtrlsModAtSubmit,
public: nsACString& aCharset);
/**
/** * Get the encoder for a form (suitable to pass in to the constructor).
* @param aCharset the charset of the form as a string * @param aForm the form in question
* @param aEncoder an encoder that will encode Unicode names and values into * @param aCharset the charset of the form
* bytes to be sent over the wire (usually a charset transformation) * @param aEncoder the returned encoder [OUT]
* @param aFormProcessor a form processor who can listen to */
* @param aBidiOptions the BIDI options flags for the current pres context static nsresult GetEncoder(nsGenericHTMLElement* aForm,
*/ const nsACString& aCharset,
nsFormSubmission(const nsACString& aCharset, nsISaveAsCharset** aEncoder);
nsISaveAsCharset* aEncoder, /**
nsIFormProcessor* aFormProcessor, * Get an attribute of a form as int, provided that it is an enumerated value.
PRInt32 aBidiOptions) * @param aForm the form in question
: mCharset(aCharset), * @param aAtom the attribute (for example, nsGkAtoms::enctype) to get
mEncoder(aEncoder), * @param aValue the result (will not be set at all if the attribute does not
mFormProcessor(aFormProcessor), * exist on the form, so *make sure you provide a default value*.)
mBidiOptions(aBidiOptions) * [OUT]
{ */
} static void GetEnumAttr(nsGenericHTMLElement* aForm,
virtual ~nsFormSubmission() nsIAtom* aAtom, PRInt32* aValue);
{
}
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 helper methods that don't really have nothing to do with nsFormSub // 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 * 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
*/
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 aWarningName the internationalized name of the warning within * @param aWarningName the internationalized name of the warning within
* layout/html/forms/src/HtmlProperties.js * layout/html/forms/src/HtmlProperties.js
* @param aWarningArgs an array of strings to replace %S's in the warning * @param aWarningArgs an array of strings to replace %S's in the warning
* @param aWarningArgsLen the number of strings in the array * @param aWarningArgsLen the number of strings in the array
*/ */
static nsresult static void
SendJSWarning(nsIContent* aContent, SendJSWarning(nsIDocument* aDocument,
const char* aWarningName, const char* aWarningName,
const PRUnichar** aWarningArgs, PRUint32 aWarningArgsLen); const PRUnichar** aWarningArgs, PRUint32 aWarningArgsLen);
@ -254,40 +128,27 @@ public:
* @param aCharset the charset of the form as a string * @param aCharset the charset of the form as a string
* @param aEncoder an encoder that will encode Unicode names and values into * @param aEncoder an encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation) * 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 aBidiOptions the BIDI options flags for the current pres context
* @param aMethod the method of the submit (either NS_FORM_METHOD_GET or * @param aMethod the method of the submit (either NS_FORM_METHOD_GET or
* NS_FORM_METHOD_POST). * NS_FORM_METHOD_POST).
*/ */
nsFSURLEncoded(const nsACString& aCharset, nsFSURLEncoded(const nsACString& aCharset,
nsISaveAsCharset* aEncoder, nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions, PRInt32 aBidiOptions,
PRInt32 aMethod) PRInt32 aMethod,
: nsFormSubmission(aCharset, aEncoder, aFormProcessor, aBidiOptions), nsIDocument* aDocument)
mMethod(aMethod) : nsFormSubmission(aCharset, aEncoder, aBidiOptions),
{ mMethod(aMethod),
} mDocument(aDocument),
virtual ~nsFSURLEncoded() mWarnedFileControl(PR_FALSE)
{ {
} }
// nsIFormSubmission // nsFormSubmission
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue); const nsAString& aValue);
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile);
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome);
virtual PRBool AcceptsFiles() const
{
return PR_FALSE;
}
NS_IMETHOD Init();
protected: protected:
// nsFormSubmission // nsFormSubmission
@ -315,43 +176,22 @@ private:
/** The query string so far (the part after the ?) */ /** The query string so far (the part after the ?) */
nsCString mQueryString; 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 */ /** Whether or not we have warned about a file control not being submitted */
PRBool mWarnedFileControl; PRBool mWarnedFileControl;
}; };
nsresult nsresult
nsFSURLEncoded::AddNameValuePair(nsIDOMHTMLElement* aSource, nsFSURLEncoded::AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue) 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 // Encode value
// //
nsCString convValue; nsCString convValue;
if (NS_SUCCEEDED(rv)) { nsresult rv = URLEncode(aValue, convValue);
rv = URLEncode(processedValue, convValue);
}
else {
rv = URLEncode(aValue, convValue);
}
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
// //
@ -376,25 +216,20 @@ nsFSURLEncoded::AddNameValuePair(nsIDOMHTMLElement* aSource,
} }
nsresult nsresult
nsFSURLEncoded::AddNameFilePair(nsIDOMHTMLElement* aSource, nsFSURLEncoded::AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile)
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome)
{ {
return AddNameValuePair(aSource, aName, aFilename); if (!mWarnedFileControl) {
} SendJSWarning(mDocument, "ForgotFileEnctypeWarning", nsnull, 0);
mWarnedFileControl = PR_TRUE;
}
// nsAutoString filename;
// nsFormSubmission if (aFile) {
// aFile->GetLeafName(filename);
NS_IMETHODIMP }
nsFSURLEncoded::Init()
{ return AddNameValuePair(aName, filename);
mQueryString.Truncate();
mWarnedFileControl = PR_FALSE;
return NS_OK;
} }
static void static void
@ -603,31 +438,17 @@ public:
* @param aCharset the charset of the form as a string * @param aCharset the charset of the form as a string
* @param aEncoder an encoder that will encode Unicode names and values into * @param aEncoder an encoder that will encode Unicode names and values into
* bytes to be sent over the wire (usually a charset transformation) * 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 aBidiOptions the BIDI options flags for the current pres context
*/ */
nsFSMultipartFormData(const nsACString& aCharset, nsFSMultipartFormData(const nsACString& aCharset,
nsISaveAsCharset* aEncoder, nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions); PRInt32 aBidiOptions);
virtual ~nsFSMultipartFormData() { }
// nsIFormSubmission // nsFormSubmission
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue); const nsAString& aValue);
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile);
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome);
virtual PRBool AcceptsFiles() const
{
return PR_TRUE;
}
NS_IMETHOD Init();
protected: protected:
// nsFormSubmission // nsFormSubmission
@ -639,34 +460,8 @@ protected:
* Roll up the data we have so far and add it to the multiplexed data stream. * Roll up the data we have so far and add it to the multiplexed data stream.
*/ */
nsresult AddPostDataStream(); 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: 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 * 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 * chunks--string streams and file streams interleaved to make one big POST
@ -696,66 +491,37 @@ private:
// //
nsFSMultipartFormData::nsFSMultipartFormData(const nsACString& aCharset, nsFSMultipartFormData::nsFSMultipartFormData(const nsACString& aCharset,
nsISaveAsCharset* aEncoder, nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions) PRInt32 aBidiOptions)
: nsFormSubmission(aCharset, aEncoder, aFormProcessor, aBidiOptions) : nsFormSubmission(aCharset, aEncoder, aBidiOptions)
{ {
// XXX I can't *believe* we have a pref for this. ifdef, anyone? mPostDataStream =
mBackwardsCompatibleSubmit = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
nsContentUtils::GetBoolPref("browser.forms.submit.backwards_compatible");
}
nsresult mBoundary.AssignLiteral("---------------------------");
nsFSMultipartFormData::ProcessAndEncode(nsIDOMHTMLElement* aSource, mBoundary.AppendInt(rand());
const nsAString& aName, mBoundary.AppendInt(rand());
const nsAString& aValue, mBoundary.AppendInt(rand());
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;
} }
// //
// nsIFormSubmission // nsFormSubmission
// //
nsresult nsresult
nsFSMultipartFormData::AddNameValuePair(nsIDOMHTMLElement* aSource, nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue) const nsAString& aValue)
{ {
nsCAutoString nameStr;
nsCString valueStr; 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); NS_ENSURE_SUCCESS(rv, rv);
// //
@ -774,29 +540,65 @@ nsFSMultipartFormData::AddNameValuePair(nsIDOMHTMLElement* aSource,
} }
nsresult nsresult
nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource, nsFSMultipartFormData::AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile)
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome)
{ {
// Encode the control name
nsCAutoString nameStr; nsCAutoString nameStr;
nsCAutoString filenameStr; nsresult rv = EncodeVal(aName, nameStr);
nsresult rv = ProcessAndEncode(aSource, aName, aFilename, nameStr, filenameStr);
NS_ENSURE_SUCCESS(rv, rv); 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 // Make MIME block for name/value pair
// //
// more appropriate than always using binary? // more appropriate than always using binary?
mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary
+ NS_LITERAL_CSTRING(CRLF); + 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 // XXX: name/filename parameter should be encoded per RFC 2231
// RFC 2388 specifies that RFC 2047 be used, but I think it's not // RFC 2388 specifies that RFC 2047 be used, but I think it's not
// consistent with the MIME standard. // consistent with the MIME standard.
@ -804,18 +606,18 @@ nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource,
NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"") NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
+ nameStr + NS_LITERAL_CSTRING("\"; filename=\"") + nameStr + NS_LITERAL_CSTRING("\"; filename=\"")
+ filenameStr + NS_LITERAL_CSTRING("\"" CRLF) + filenameStr + NS_LITERAL_CSTRING("\"" CRLF)
+ NS_LITERAL_CSTRING("Content-Type: ") + aContentType + NS_LITERAL_CSTRING("Content-Type: ") + contentType
+ NS_LITERAL_CSTRING(CRLF CRLF); + NS_LITERAL_CSTRING(CRLF CRLF);
// //
// Add the file to the stream // 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, // 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 // since we're about to add the file input stream
AddPostDataStream(); AddPostDataStream();
mPostDataStream->AppendStream(aStream); mPostDataStream->AppendStream(fileStream);
} }
// //
@ -826,35 +628,6 @@ nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource,
return NS_OK; 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 NS_IMETHODIMP
nsFSMultipartFormData::GetEncodedSubmission(nsIURI* aURI, nsFSMultipartFormData::GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream) nsIInputStream** aPostDataStream)
@ -920,86 +693,49 @@ class nsFSTextPlain : public nsFormSubmission
public: public:
nsFSTextPlain(const nsACString& aCharset, nsFSTextPlain(const nsACString& aCharset,
nsISaveAsCharset* aEncoder, nsISaveAsCharset* aEncoder,
nsIFormProcessor* aFormProcessor,
PRInt32 aBidiOptions) PRInt32 aBidiOptions)
: nsFormSubmission(aCharset, aEncoder, aFormProcessor, aBidiOptions) : nsFormSubmission(aCharset, aEncoder, aBidiOptions)
{
}
virtual ~nsFSTextPlain()
{ {
} }
// nsIFormSubmission // nsFormSubmission
virtual nsresult AddNameValuePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue); const nsAString& aValue);
virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource, virtual nsresult AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile);
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome);
NS_IMETHOD Init();
protected: protected:
// nsFormSubmission // nsFormSubmission
NS_IMETHOD GetEncodedSubmission(nsIURI* aURI, NS_IMETHOD GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream); nsIInputStream** aPostDataStream);
virtual PRBool AcceptsFiles() const
{
return PR_FALSE;
}
private: private:
nsString mBody; nsString mBody;
}; };
nsresult nsresult
nsFSTextPlain::AddNameValuePair(nsIDOMHTMLElement* aSource, nsFSTextPlain::AddNameValuePair(const nsAString& aName,
const nsAString& aName,
const nsAString& aValue) 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 // 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 // text/plain doesn't care about that. Parsers aren't built for escaped
// values so we'll have to live with it. // values so we'll have to live with it.
if (NS_SUCCEEDED(rv)) { mBody.Append(aName + NS_LITERAL_STRING("=") + aValue +
mBody.Append(aName + NS_LITERAL_STRING("=") + processedValue + NS_LITERAL_STRING(CRLF));
NS_LITERAL_STRING(CRLF));
} else {
mBody.Append(aName + NS_LITERAL_STRING("=") + aValue +
NS_LITERAL_STRING(CRLF));
}
return NS_OK; return NS_OK;
} }
nsresult nsresult
nsFSTextPlain::AddNameFilePair(nsIDOMHTMLElement* aSource, nsFSTextPlain::AddNameFilePair(const nsAString& aName,
const nsAString& aName, nsIFile* aFile)
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome)
{ {
AddNameValuePair(aSource,aName,aFilename); nsAutoString filename;
return NS_OK; if (aFile) {
} aFile->GetLeafName(filename);
}
//
// nsFormSubmission AddNameValuePair(aName, filename);
//
NS_IMETHODIMP
nsFSTextPlain::Init()
{
mBody.Truncate();
return NS_OK; return NS_OK;
} }
@ -1033,7 +769,6 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
rv = aURI->SetPath(path); rv = aURI->SetPath(path);
} else { } else {
// Create data stream // Create data stream
nsCOMPtr<nsIInputStream> bodyStream; nsCOMPtr<nsIInputStream> bodyStream;
rv = NS_NewStringInputStream(getter_AddRefs(bodyStream), rv = NS_NewStringInputStream(getter_AddRefs(bodyStream),
@ -1056,65 +791,49 @@ nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
return rv; return rv;
} }
nsFormSubmission::nsFormSubmission(const nsACString& aCharset,
// nsISaveAsCharset* aEncoder,
// CLASS nsFormSubmission PRInt32 aBidiOptions)
// : mCharset(aCharset),
mEncoder(aEncoder),
// mBidiOptions(aBidiOptions)
// nsISupports stuff
//
NS_IMPL_ISUPPORTS1(nsFormSubmission, nsIFormSubmission)
// JBK moved from nsFormFrame - bug 34297
// submission
static nsresult
SendJSWarning(nsIContent* aContent,
const char* aWarningName)
{ {
return SendJSWarning(aContent, aWarningName, nsnull, 0);
} }
static nsresult nsFormSubmission::~nsFormSubmission()
SendJSWarning(nsIContent* aContent,
const char* aWarningName,
const nsAFlatString& aWarningArg1)
{ {
const PRUnichar* formatStrings[1] = { aWarningArg1.get() };
return SendJSWarning(aContent, aWarningName, formatStrings, 1);
} }
static nsresult void
SendJSWarning(nsIContent* aContent, 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 char* aWarningName,
const PRUnichar** aWarningArgs, PRUint32 aWarningArgsLen) const PRUnichar** aWarningArgs, PRUint32 aWarningArgsLen)
{ {
// Get the document URL to use as the filename nsContentUtils::ReportToConsole(nsContentUtils::eFORMS_PROPERTIES,
aWarningName,
nsIDocument* document = aContent->GetDocument(); aWarningArgs, aWarningArgsLen,
nsIURI *documentURI = nsnull; aDocument ? aDocument->GetDocumentURI() :
if (document) { nsnull,
documentURI = document->GetDocumentURI(); EmptyString(), 0, 0,
NS_ENSURE_TRUE(documentURI, NS_ERROR_UNEXPECTED); nsIScriptError::warningFlag,
} "HTML");
return nsContentUtils::ReportToConsole(nsContentUtils::eFORMS_PROPERTIES,
aWarningName,
aWarningArgs, aWarningArgsLen,
documentURI,
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"HTML");
} }
nsresult nsresult
GetSubmissionFromForm(nsGenericHTMLElement* aForm, GetSubmissionFromForm(nsGenericHTMLElement* aForm,
nsIFormSubmission** aFormSubmission) nsFormSubmission** aFormSubmission)
{ {
nsresult rv = NS_OK;
// //
// Get all the information necessary to encode the form data // Get all the information necessary to encode the form data
// //
@ -1128,23 +847,19 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
// Get encoding type (default: urlencoded) // Get encoding type (default: urlencoded)
PRInt32 enctype = NS_FORM_ENCTYPE_URLENCODED; PRInt32 enctype = NS_FORM_ENCTYPE_URLENCODED;
nsFormSubmission::GetEnumAttr(aForm, nsGkAtoms::enctype, &enctype); GetEnumAttr(aForm, nsGkAtoms::enctype, &enctype);
// Get method (default: GET) // Get method (default: GET)
PRInt32 method = NS_FORM_METHOD_GET; PRInt32 method = NS_FORM_METHOD_GET;
nsFormSubmission::GetEnumAttr(aForm, nsGkAtoms::method, &method); GetEnumAttr(aForm, nsGkAtoms::method, &method);
// Get charset // Get charset
nsCAutoString charset; nsCAutoString charset;
nsFormSubmission::GetSubmitCharset(aForm, ctrlsModAtSubmit, charset); GetSubmitCharset(aForm, ctrlsModAtSubmit, charset);
// Get unicode encoder // Get unicode encoder
nsCOMPtr<nsISaveAsCharset> encoder; nsCOMPtr<nsISaveAsCharset> encoder;
nsFormSubmission::GetEncoder(aForm, charset, getter_AddRefs(encoder)); GetEncoder(aForm, charset, getter_AddRefs(encoder));
// Get form processor
nsCOMPtr<nsIFormProcessor> formProcessor =
do_GetService(kFormProcessorCID, &rv);
// //
// Choose encoder // Choose encoder
@ -1157,29 +872,25 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
if (method == NS_FORM_METHOD_POST && if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_MULTIPART) { enctype == NS_FORM_ENCTYPE_MULTIPART) {
*aFormSubmission = new nsFSMultipartFormData(charset, encoder, *aFormSubmission = new nsFSMultipartFormData(charset, encoder,
formProcessor, bidiOptions); bidiOptions);
} else if (method == NS_FORM_METHOD_POST && } else if (method == NS_FORM_METHOD_POST &&
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) { enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
*aFormSubmission = new nsFSTextPlain(charset, encoder, *aFormSubmission = new nsFSTextPlain(charset, encoder, bidiOptions);
formProcessor, bidiOptions);
} else { } else {
if (enctype == NS_FORM_ENCTYPE_MULTIPART || if (enctype == NS_FORM_ENCTYPE_MULTIPART ||
enctype == NS_FORM_ENCTYPE_TEXTPLAIN) { enctype == NS_FORM_ENCTYPE_TEXTPLAIN) {
nsAutoString enctypeStr; nsAutoString enctypeStr;
aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::enctype, 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, *aFormSubmission = new nsFSURLEncoded(charset, encoder, bidiOptions,
formProcessor, bidiOptions, method); method, aForm->GetOwnerDoc());
} }
NS_ENSURE_TRUE(*aFormSubmission, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(*aFormSubmission, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(*aFormSubmission); 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; return NS_OK;
} }
@ -1208,12 +919,10 @@ nsFormSubmission::SubmitTo(nsIURI* aActionURI, const nsAString& aTarget,
aDocShell, aRequest); aDocShell, aRequest);
} }
// JBK moved from nsFormFrame - bug 34297
// static
void void
nsFormSubmission::GetSubmitCharset(nsGenericHTMLElement* aForm, GetSubmitCharset(nsGenericHTMLElement* aForm,
PRUint8 aCtrlsModAtSubmit, PRUint8 aCtrlsModAtSubmit,
nsACString& oCharset) nsACString& oCharset)
{ {
oCharset.AssignLiteral("UTF-8"); // default to utf-8 oCharset.AssignLiteral("UTF-8"); // default to utf-8
@ -1279,12 +988,10 @@ nsFormSubmission::GetSubmitCharset(nsGenericHTMLElement* aForm,
} }
// JBK moved from nsFormFrame - bug 34297
// static
nsresult nsresult
nsFormSubmission::GetEncoder(nsGenericHTMLElement* aForm, GetEncoder(nsGenericHTMLElement* aForm,
const nsACString& aCharset, const nsACString& aCharset,
nsISaveAsCharset** aEncoder) nsISaveAsCharset** aEncoder)
{ {
*aEncoder = nsnull; *aEncoder = nsnull;
nsresult rv = NS_OK; nsresult rv = NS_OK;
@ -1385,8 +1092,8 @@ nsFormSubmission::UnicodeToNewBytes(const nsAString& aStr,
// static // static
void void
nsFormSubmission::GetEnumAttr(nsGenericHTMLElement* aContent, GetEnumAttr(nsGenericHTMLElement* aContent,
nsIAtom* atom, PRInt32* aValue) nsIAtom* atom, PRInt32* aValue)
{ {
const nsAttrValue* value = aContent->GetParsedAttr(atom); const nsAttrValue* value = aContent->GetParsedAttr(atom);
if (value && value->Type() == nsAttrValue::eEnum) { if (value && value->Type() == nsAttrValue::eEnum) {
@ -1405,27 +1112,3 @@ nsFormSubmission::EncodeVal(const nsAString& aStr, nsACString& aOut)
CopyUTF16toUTF8(aStr, aOut); CopyUTF16toUTF8(aStr, aOut);
return NS_OK; 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 // overriden nsIFormControl methods
NS_IMETHOD_(PRInt32) GetType() const { return mType; } NS_IMETHOD_(PRInt32) GetType() const { return mType; }
NS_IMETHOD Reset(); NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission, NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement); nsIContent* aSubmitElement);
NS_IMETHOD SaveState(); NS_IMETHOD SaveState();
PRBool RestoreState(nsPresState* aState); PRBool RestoreState(nsPresState* aState);
@ -503,7 +503,7 @@ nsHTMLButtonElement::Reset()
} }
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLButtonElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission, nsHTMLButtonElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement) nsIContent* aSubmitElement)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
@ -545,7 +545,7 @@ nsHTMLButtonElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
// //
// Submit // Submit
// //
rv = aFormSubmission->AddNameValuePair(this, name, value); rv = aFormSubmission->AddNameValuePair(name, value);
return rv; return rv;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -47,6 +47,7 @@
#include "nsMappedAttributes.h" #include "nsMappedAttributes.h"
#include "nsIForm.h" #include "nsIForm.h"
#include "nsIFormSubmission.h" #include "nsIFormSubmission.h"
#include "nsIFormProcessor.h"
#include "nsIDOMHTMLOptGroupElement.h" #include "nsIDOMHTMLOptGroupElement.h"
#include "nsIOptionElement.h" #include "nsIOptionElement.h"
@ -66,6 +67,7 @@
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsDOMError.h" #include "nsDOMError.h"
#include "nsServiceManagerUtils.h"
#include "nsRuleData.h" #include "nsRuleData.h"
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
@ -1582,8 +1584,10 @@ nsHTMLSelectElement::Reset()
return NS_OK; return NS_OK;
} }
static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
NS_IMETHODIMP NS_IMETHODIMP
nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission, nsHTMLSelectElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
nsIContent* aSubmitElement) nsIContent* aSubmitElement)
{ {
nsresult rv = NS_OK; nsresult rv = NS_OK;
@ -1612,6 +1616,13 @@ nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
PRUint32 len; PRUint32 len;
GetLength(&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++) { for (PRUint32 optIndex = 0; optIndex < len; optIndex++) {
// Don't send disabled options // Don't send disabled options
PRBool disabled; PRBool disabled;
@ -1637,7 +1648,15 @@ nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
rv = optionElement->GetValue(value); rv = optionElement->GetValue(value);
NS_ENSURE_SUCCESS(rv, rv); 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; return NS_OK;

View File

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

View File

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

View File

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

View File

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