Bug 544698 part 1: Move value processing from submission code to elements. Decomtaminate. Kill a few dead functions. r=jst
authorJonas Sicking <jonas@sicking.cc>
Wed, 24 Feb 2010 21:58:16 -0800
changeset 38672 38c07ace8a849caff8acf77c9d17829b8d17c319
parent 38671 40326c4f714c69b4beefe90d39c3cf1638060ff1
child 38673 9b590d74d8a65e90bfa0df765e6ea7a021136ad5
push id11798
push usersicking@mozilla.com
push dateThu, 25 Feb 2010 06:06:03 +0000
treeherderautoland@00bc3f167040 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs544698
milestone1.9.3a2pre
Bug 544698 part 1: Move value processing from submission code to elements. Decomtaminate. Kill a few dead functions. r=jst
content/base/src/nsGkAtomList.h
content/html/content/public/nsIFormControl.h
content/html/content/public/nsIFormSubmission.h
content/html/content/src/nsFormSubmission.cpp
content/html/content/src/nsHTMLButtonElement.cpp
content/html/content/src/nsHTMLFieldSetElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLFormElement.h
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLLabelElement.cpp
content/html/content/src/nsHTMLLegendElement.cpp
content/html/content/src/nsHTMLObjectElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/html/content/src/nsHTMLTextAreaElement.cpp
modules/libpref/src/init/all.js
security/manager/ssl/src/nsKeygenHandler.cpp
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -64,16 +64,17 @@
 GK_ATOM(_empty, "")
 GK_ATOM(moz, "_moz")
 GK_ATOM(mozdirty, "_moz_dirty")
 GK_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
 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, "*")
 GK_ATOM(a, "a")
 GK_ATOM(abbr, "abbr")
 GK_ATOM(abort, "abort")
 GK_ATOM(above, "above")
 GK_ATOM(absoluteList, "Absolute-list")
--- a/content/html/content/public/nsIFormControl.h
+++ b/content/html/content/public/nsIFormControl.h
@@ -39,17 +39,17 @@
 
 #include "nsISupports.h"
 class nsIDOMHTMLFormElement;
 class nsPresContext;
 class nsPresState;
 class nsIContent;
 class nsString;
 class nsIFormProcessor;
-class nsIFormSubmission;
+class nsFormSubmission;
 
 #define NS_FORM_BUTTON_BUTTON   1
 #define NS_FORM_BUTTON_RESET    2
 #define NS_FORM_BUTTON_SUBMIT   3
 #define NS_FORM_FIELDSET        4
 #define NS_FORM_INPUT_BUTTON    5
 #define NS_FORM_INPUT_CHECKBOX  6
 #define NS_FORM_INPUT_FILE      7
@@ -124,17 +124,17 @@ public:
   /**
    * Tells the form control to submit its names and values to the form
    * submission object
    * @param aFormSubmission the form submission to notify of names/values/files
    *                       to submit
    * @param aSubmitElement the element that was pressed to submit (possibly
    *                       null)
    */
-  NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
+  NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                nsIContent* aSubmitElement) = 0;
 
   /**
    * Save to presentation state.  The form control will determine whether it
    * has anything to save and if so, create an entry in the layout history for
    * its pres context.
    */
   NS_IMETHOD SaveState() = 0;
--- a/content/html/content/public/nsIFormSubmission.h
+++ b/content/html/content/public/nsIFormSubmission.h
@@ -33,105 +33,142 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsIFormSubmission_h___
 #define nsIFormSubmission_h___
 
 #include "nsISupports.h"
-class nsAString;
-class nsACString;
+#include "nsString.h"
+#include "nsCOMPtr.h"
+
 class nsIURI;
 class nsIInputStream;
 class nsGenericHTMLElement;
 class nsILinkHandler;
 class nsIContent;
 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:
-
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFORMSUBMISSION_IID)
+  virtual ~nsFormSubmission();
 
-  /**
-   * 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
    *
    * @param aActionURL the URL to submit to (may be modified with GET contents)
    * @param aTarget the target window
    * @param aSource the element responsible for the submission (for web shell)
    * @param aLinkHandler the link handler to use
    * @param aDocShell (out param) the DocShell in which the submission was
    *        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(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
    */
-  virtual nsresult AddNameFilePair(nsIDOMHTMLElement* aSource,
-                               const nsAString& aName,
-                               const nsAString& aFilename,
-                               nsIInputStream* aStream,
-                               const nsACString& aContentType,
-                               PRBool aMoreFilesToCome) = 0;
+  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)
  *
  * @param aForm the form to get a submission object based on
  * @param aFormSubmission the form submission object (out param)
  */
 nsresult GetSubmissionFromForm(nsGenericHTMLElement* aForm,
-                               nsIFormSubmission** aFormSubmission);
+                               nsFormSubmission** aFormSubmission);
 
 
 #endif /* nsIFormSubmission_h___ */
--- a/content/html/content/src/nsFormSubmission.cpp
+++ b/content/html/content/src/nsFormSubmission.cpp
@@ -50,249 +50,110 @@
 #include "nsDOMError.h"
 #include "nsGenericHTMLElement.h"
 #include "nsISaveAsCharset.h"
 
 // JBK added for submit move from content frame
 #include "nsIFile.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsStringStream.h"
-#include "nsIFormProcessor.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsLinebreakConverter.h"
 #include "nsICharsetConverterManager.h"
 #include "nsICharsetAlias.h"
 #include "nsEscape.h"
 #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
 //
 
 /**
  * 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);
 
 
 class nsFSURLEncoded : public nsFormSubmission
 {
 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
   NS_IMETHOD GetEncodedSubmission(nsIURI* aURI,
                                   nsIInputStream** aPostDataStream);
 
   // Helpers
   /**
@@ -310,53 +171,32 @@ private:
    * The method of the submit (either NS_FORM_METHOD_GET or
    * NS_FORM_METHOD_POST).
    */
   PRInt32 mMethod;
 
   /** 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);
 
   //
   // Encode name
   //
   nsCAutoString convName;
   rv = URLEncode(aName, convName);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -371,35 +211,30 @@ nsFSURLEncoded::AddNameValuePair(nsIDOMH
     mQueryString += NS_LITERAL_CSTRING("&") + convName
                   + NS_LITERAL_CSTRING("=") + convValue;
   }
 
   return NS_OK;
 }
 
 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
 HandleMailtoSubject(nsCString& aPath) {
 
   // Walk through the string and see if we have a subject already.
   PRBool hasSubject = PR_FALSE;
   PRBool hasParams = PR_FALSE;
@@ -598,81 +433,41 @@ nsFSURLEncoded::URLEncode(const nsAStrin
  */
 class nsFSMultipartFormData : public nsFormSubmission
 {
 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
   NS_IMETHOD GetEncodedSubmission(nsIURI* aURI,
                                   nsIInputStream** aPostDataStream);
 
   // Helpers
   /**
    * 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
    * stream.
    */
   nsCOMPtr<nsIMultiplexInputStream> mPostDataStream;
 
   /**
    * The current string chunk.  When a file is hit, the string chunk gets
@@ -691,76 +486,47 @@ private:
   nsCString mBoundary;
 };
 
 //
 // Constructor
 //
 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");
-}
-
-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);
+  mPostDataStream =
+    do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1");
 
-  //
-  // 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)
 {
+  nsCString 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;
-  nsCString valueStr;
-  nsresult rv = ProcessAndEncode(aSource, aName, aValue, nameStr, valueStr);
+  rv = EncodeVal(aName, nameStr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   //
   // Make MIME block for name/value pair
   //
   // XXX: name parameter should be encoded per RFC 2231
   // RFC 2388 specifies that RFC 2047 be used, but I think it's not 
   // consistent with MIME standard.
@@ -769,97 +535,104 @@ nsFSMultipartFormData::AddNameValuePair(
                  + NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
                  + nameStr + NS_LITERAL_CSTRING("\"" CRLF CRLF)
                  + valueStr + NS_LITERAL_CSTRING(CRLF);
 
   return NS_OK;
 }
 
 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.
   mPostDataChunk +=
          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);
   }
 
   //
   // CRLF after file
   //
   mPostDataChunk.AppendLiteral(CRLF);
 
   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)
 {
   nsresult rv;
 
   //
   // Finish data
@@ -915,96 +688,59 @@ nsFSMultipartFormData::AddPostDataStream
 //
 // CLASS nsFSTextPlain
 //
 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;
-}
-
-//
-// nsFormSubmission
-//
-NS_IMETHODIMP
-nsFSTextPlain::Init()
-{
-  mBody.Truncate();
+  nsAutoString filename;
+  if (aFile) {
+    aFile->GetLeafName(filename);
+  }
+    
+  AddNameValuePair(aName, filename);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFSTextPlain::GetEncodedSubmission(nsIURI* aURI,
                                     nsIInputStream** aPostDataStream)
 {
   nsresult rv = NS_OK;
@@ -1028,17 +764,16 @@ nsFSTextPlain::GetEncodedSubmission(nsIU
     nsCString escapedBody;
     escapedBody.Adopt(escapedBuf);
 
     path += NS_LITERAL_CSTRING("&force-plain-text=Y&body=") + escapedBody;
 
     rv = aURI->SetPath(path);
 
   } else {
-
     // Create data stream
     nsCOMPtr<nsIInputStream> bodyStream;
     rv = NS_NewStringInputStream(getter_AddRefs(bodyStream),
                                           mBody);
     if (!bodyStream) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
@@ -1051,140 +786,116 @@ nsFSTextPlain::GetEncodedSubmission(nsIU
     mimeStream->SetAddContentLength(PR_TRUE);
     mimeStream->SetData(bodyStream);
     CallQueryInterface(mimeStream, aPostDataStream);
   }
 
   return rv;
 }
 
-
-//
-// CLASS nsFormSubmission
-//
-
-//
-// nsISupports stuff
-//
+nsFormSubmission::nsFormSubmission(const nsACString& aCharset,
+                                   nsISaveAsCharset* aEncoder,
+                                   PRInt32 aBidiOptions)
+  : mCharset(aCharset),
+    mEncoder(aEncoder),
+    mBidiOptions(aBidiOptions)
+{
+}
 
-NS_IMPL_ISUPPORTS1(nsFormSubmission, nsIFormSubmission)
-
-// JBK moved from nsFormFrame - bug 34297
-// submission
-
-static nsresult
-SendJSWarning(nsIContent* aContent,
-               const char* aWarningName)
+nsFormSubmission::~nsFormSubmission()
 {
-  return SendJSWarning(aContent, aWarningName, nsnull, 0);
 }
 
-static nsresult
-SendJSWarning(nsIContent* aContent,
-               const char* aWarningName,
-               const nsAFlatString& aWarningArg1)
+void
+nsFormSubmission::Release()
 {
-  const PRUnichar* formatStrings[1] = { aWarningArg1.get() };
-  return SendJSWarning(aContent, aWarningName, formatStrings, 1);
+  --mRefCnt;
+  NS_LOG_RELEASE(this, mRefCnt, "nsFormSubmission");
+  if (mRefCnt == 0) {
+    mRefCnt = 1; // stabilize
+    delete this;
+  }
 }
 
-static nsresult
-SendJSWarning(nsIContent* aContent,
+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
   //
   nsIDocument* doc = aForm->GetCurrentDoc();
   NS_ASSERTION(doc, "Should have doc if we're building submission!");
 
   // Get BIDI options
   PRUint8 ctrlsModAtSubmit = 0;
   PRUint32 bidiOptions = doc->GetBidiOptions();
   ctrlsModAtSubmit = GET_BIDI_OPTION_CONTROLSTEXTMODE(bidiOptions);
 
   // 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
   //
   // If enctype=multipart/form-data and method=post, do multipart
   // Else do URL encoded
   // NOTE:
   // The rule used to be, if enctype=multipart/form-data, do multipart
   // Else do URL encoded
   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;
 }
 
 nsresult
 nsFormSubmission::SubmitTo(nsIURI* aActionURI, const nsAString& aTarget,
                            nsIContent* aSource, nsILinkHandler* aLinkHandler,
                            nsIDocShell** aDocShell, nsIRequest** aRequest)
 {
@@ -1203,22 +914,20 @@ nsFormSubmission::SubmitTo(nsIURI* aActi
   NS_ENSURE_ARG_POINTER(aLinkHandler);
 
   return aLinkHandler->OnLinkClickSync(aSource, aActionURI,
                                        PromiseFlatString(aTarget).get(),
                                        postDataStream, nsnull,
                                        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
 
   nsresult rv = NS_OK;
   nsAutoString acceptCharsetValue;
   aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::acceptcharset,
                  acceptCharsetValue);
 
@@ -1274,22 +983,20 @@ nsFormSubmission::GetSubmitCharset(nsGen
   else if (aCtrlsModAtSubmit==IBMBIDI_CONTROLSTEXTMODE_VISUAL
           && oCharset.Equals(NS_LITERAL_CSTRING("UTF-8"),
                              nsCaseInsensitiveCStringComparator())) {
     oCharset.AssignLiteral("IBM864");
   }
 
 }
 
-// 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;
 
   nsCAutoString charset(aCharset);
   // canonical name is passed so that we just have to check against
   // *our* canonical names listed in charsetaliases.properties
   if (charset.EqualsLiteral("ISO-8859-1")) {
@@ -1380,18 +1087,18 @@ nsFormSubmission::UnicodeToNewBytes(cons
 
   aOut = res;
   return NS_OK;
 }
 
 
 // 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) {
     *aValue = value->GetEnumValue();
   }
 }
 
 nsresult
@@ -1400,32 +1107,8 @@ nsFormSubmission::EncodeVal(const nsAStr
   NS_ASSERTION(mEncoder, "Encoder not available. Losing data !");
   if (mEncoder)
     return UnicodeToNewBytes(aStr, mEncoder, aOut);
 
   // fall back to UTF-8
   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;
-}
--- a/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/content/html/content/src/nsHTMLButtonElement.cpp
@@ -95,17 +95,17 @@ public:
   NS_IMETHOD Blur();
   NS_IMETHOD Focus();
   NS_IMETHOD Click();
   NS_IMETHOD SetType(const nsAString& aType);
 
   // 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);
 
   /**
    * Called when an attribute is about to be changed
    */
   virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
@@ -498,17 +498,17 @@ nsHTMLButtonElement::SetDefaultValue(con
 
 NS_IMETHODIMP
 nsHTMLButtonElement::Reset()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLButtonElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
+nsHTMLButtonElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                        nsIContent* aSubmitElement)
 {
   nsresult rv = NS_OK;
 
   //
   // We only submit if we were the button pressed
   //
   if (aSubmitElement != this) {
@@ -540,17 +540,17 @@ nsHTMLButtonElement::SubmitNamesValues(n
   rv = GetValue(value);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   //
   // Submit
   //
-  rv = aFormSubmission->AddNameValuePair(this, name, value);
+  rv = aFormSubmission->AddNameValuePair(name, value);
 
   return rv;
 }
 
 void
 nsHTMLButtonElement::DoneCreatingElement()
 {
   // Restore state as needed.
--- a/content/html/content/src/nsHTMLFieldSetElement.cpp
+++ b/content/html/content/src/nsHTMLFieldSetElement.cpp
@@ -64,17 +64,17 @@ public:
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLFieldSetElement
   NS_DECL_NSIDOMHTMLFIELDSETELEMENT
 
   // 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;
 };
 
 // construction, destruction
 
 
 NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
@@ -122,13 +122,13 @@ nsHTMLFieldSetElement::GetForm(nsIDOMHTM
 
 nsresult
 nsHTMLFieldSetElement::Reset()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLFieldSetElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
+nsHTMLFieldSetElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                          nsIContent* aSubmitElement)
 {
   return NS_OK;
 }
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -704,18 +704,18 @@ nsHTMLFormElement::DoSubmit(nsEvent* aEv
     // XXX Should this return an error?
     return NS_OK;
   }
 
   // Mark us as submitting so that we don't try to submit again
   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
   //
   BuildSubmission(submission, aEvent); 
 
   // XXXbz if the script global is that for an sXBL/XBL2 doc, it won't
   // be a window...
   nsPIDOMWindow *window = GetOwnerDoc()->GetWindow();
@@ -740,17 +740,17 @@ nsHTMLFormElement::DoSubmit(nsEvent* aEv
   
   // 
   // perform the submission
   //
   return SubmitSubmission(submission); 
 }
 
 nsresult
-nsHTMLFormElement::BuildSubmission(nsCOMPtr<nsIFormSubmission>& aFormSubmission, 
+nsHTMLFormElement::BuildSubmission(nsRefPtr<nsFormSubmission>& aFormSubmission, 
                                    nsEvent* aEvent)
 {
   NS_ASSERTION(!mPendingSubmission, "tried to build two submissions!");
 
   // Get the originating frame (failure is non-fatal)
   nsIContent *originatingElement = nsnull;
   if (aEvent) {
     if (NS_FORM_EVENT == aEvent->eventStructType) {
@@ -771,17 +771,17 @@ nsHTMLFormElement::BuildSubmission(nsCOM
   //
   rv = WalkFormElements(aFormSubmission, originatingElement);
   NS_ENSURE_SUBMIT_SUCCESS(rv);
 
   return NS_OK;
 }
 
 nsresult
-nsHTMLFormElement::SubmitSubmission(nsIFormSubmission* aFormSubmission)
+nsHTMLFormElement::SubmitSubmission(nsFormSubmission* aFormSubmission)
 {
   nsresult rv;
   //
   // Get the action and target
   //
   nsCOMPtr<nsIURI> actionURI;
   rv = GetActionURL(getter_AddRefs(actionURI));
   NS_ENSURE_SUBMIT_SUCCESS(rv);
@@ -942,17 +942,17 @@ nsHTMLFormElement::NotifySubmitObservers
     }
   }
 
   return rv;
 }
 
 
 nsresult
-nsHTMLFormElement::WalkFormElements(nsIFormSubmission* aFormSubmission,
+nsHTMLFormElement::WalkFormElements(nsFormSubmission* aFormSubmission,
                                     nsIContent* aSubmitElement)
 {
   nsTArray<nsGenericHTMLFormElement*> sortedControls;
   nsresult rv = mControls->GetSortedControls(sortedControls);
   NS_ENSURE_SUCCESS(rv, rv);
 
   //
   // Walk the list of nodes and call SubmitNamesValues() on the controls
@@ -1322,17 +1322,17 @@ void
 nsHTMLFormElement::OnSubmitClickEnd()
 {
   mDeferSubmission = PR_FALSE;
 }
 
 void
 nsHTMLFormElement::FlushPendingSubmission()
 {
-  nsCOMPtr<nsIFormSubmission> kunkFuDeathGrip(mPendingSubmission);
+  nsRefPtr<nsFormSubmission> kunkFuDeathGrip(mPendingSubmission);
 
   if (!mPendingSubmission) {
     return;
   }
 
   //
   // perform the submission with the stored pending submission
   //
--- a/content/html/content/src/nsHTMLFormElement.h
+++ b/content/html/content/src/nsHTMLFormElement.h
@@ -284,32 +284,32 @@ protected:
   nsresult DoSubmit(nsEvent* aEvent);
 
   /**
    * Prepare the submission object (called by DoSubmit)
    *
    * @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.
    *
    * @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);
 
   /**
    * Notify any submit observers of the submit.
    *
    * @param aActionURL the URL being submitted to
    * @param aCancelSubmit out param where submit observers can specify that the
    *        submit should be cancelled.
@@ -366,17 +366,17 @@ protected:
   /** If we notified the listeners early, what was the result? */
   PRPackedBool mNotifiedObserversResult;
   /** Keep track of what the popup state was when the submit was initiated */
   PopupControlState mSubmitPopupState;
   /** Keep track of whether a submission was user-initiated or not */
   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 */
   nsWeakPtr mWebProgress;
 
   /** The default submit element -- WEAK */
   nsGenericHTMLFormElement* mDefaultSubmitElement;
 
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -93,21 +93,18 @@
 #include "nsIEventListenerManager.h"
 
 #include "nsRuleData.h"
 
 // input type=radio
 #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"
 
 // input type=image
 #include "nsImageLoadingContent.h"
 #include "nsIDOMWindowInternal.h"
 
 #include "mozAutoDocUpdate.h"
@@ -253,17 +250,17 @@ public:
   {
     return nsGenericHTMLElement::GetEditor(aEditor);
   }
   NS_IMETHOD SetUserInput(const nsAString& aInput);
 
   // 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);
   virtual PRBool AllowDrop();
 
   // nsIContent
   virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
 
@@ -403,16 +400,24 @@ protected:
 
   /**
    * Actually set checked and notify the frame of the change.
    * @param aValue the value of checked to set
    */
   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.
    */
   nsresult MaybeSubmitForm(nsPresContext* aPresContext);
 
   /**
    * Update mFileList with the currently selected file.
    */
@@ -543,20 +548,17 @@ nsHTMLInputElement::Clone(nsINodeInfo *a
     case NS_FORM_INPUT_FILE:
       it->mFileNames = mFileNames;
       break;
     case NS_FORM_INPUT_RADIO:
     case NS_FORM_INPUT_CHECKBOX:
       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:
       if (it->GetOwnerDoc()->IsStaticDocument()) {
         CreateStaticImageClone(it);
       }
       break;
     default:
@@ -1154,17 +1156,17 @@ nsHTMLInputElement::SetValueChanged(PRBo
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsHTMLInputElement::GetChecked(PRBool* aChecked)
 {
-  *aChecked = GET_BOOLBIT(mBitField, BF_CHECKED);
+  *aChecked = GetChecked();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::SetCheckedChanged(PRBool aCheckedChanged)
 {
   return DoSetCheckedChanged(aCheckedChanged, PR_TRUE);
 }
@@ -1219,19 +1221,17 @@ nsHTMLInputElement::DoSetChecked(PRBool 
   //
   DoSetCheckedChanged(PR_TRUE, aNotify);
 
   //
   // Don't do anything if we're not changing whether it's checked (it would
   // 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;
   }
 
   //
   // Set checked
   //
   if (mType == NS_FORM_INPUT_RADIO) {
     //
@@ -1647,17 +1647,17 @@ nsHTMLInputElement::PreHandleEvent(nsEve
             if (GetNameIfExists(name)) {
               nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
               container->GetCurrentRadioButton(name,
                                                getter_AddRefs(selectedRadioButton));
               aVisitor.mItemData = selectedRadioButton;
             }
           }
 
-          GetChecked(&originalCheckedValue);
+          originalCheckedValue = GetChecked();
           if (!originalCheckedValue) {
             DoSetChecked(PR_TRUE);
             SET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED, PR_TRUE);
           }
         }
         break;
 
       case NS_FORM_INPUT_SUBMIT:
@@ -2547,66 +2547,42 @@ nsHTMLInputElement::Reset()
     default:
       break;
   }
 
   return rv;
 }
 
 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
+  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;
   }
 
-  //
-  // 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;
-    }
-  }
-
-  //
   // 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 =
       static_cast<nsIntPoint*>(GetProperty(nsGkAtoms::imageClickedPoint));
     PRInt32 x, y;
     if (lastClickedPoint) {
       // Convert the values to strings for submission
       x = lastClickedPoint->x;
@@ -2615,37 +2591,35 @@ nsHTMLInputElement::SubmitNamesValues(ns
       x = y = 0;
     }
 
     nsAutoString xVal, yVal;
     xVal.AppendInt(x);
     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;
   }
 
   //
   // Submit name=value
   //
 
   // If name not there, don't submit
   if (!nameThere) {
-    return rv;
+    return NS_OK;
   }
 
   // Get the value
   nsAutoString value;
   rv = GetValue(value);
   if (NS_FAILED(rv)) {
     return rv;
   }
@@ -2660,88 +2634,43 @@ nsHTMLInputElement::SubmitNamesValues(ns
   }
       
   //
   // Submit file if its input type=file and this encoding method accepts files
   //
   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);
 
     }
 
     return NS_OK;
   }
 
   // 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;
 }
 
 
 NS_IMETHODIMP
 nsHTMLInputElement::SaveState()
@@ -2749,18 +2678,17 @@ nsHTMLInputElement::SaveState()
   nsresult rv = NS_OK;
 
   nsRefPtr<nsHTMLInputElementState> inputState = nsnull;
 
   switch (mType) {
     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)
         // (always save if it's a radio button so that the checked
         // state of all radio buttons is restored)
         if (mType == NS_FORM_INPUT_RADIO || checked != defaultChecked) {
           inputState = new nsHTMLInputElementState();
           if (!inputState) {
@@ -2954,19 +2882,17 @@ nsHTMLInputElement::AddedToRadioGroup(PR
   if (!mForm && !(IsInDoc() && GetParent())) {
     return NS_OK;
   }
 
   //
   // 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
     // radio button, but as adding a checked radio button into the group
     // should not be that common an occurrence, I think we can live with
     // that.
     //
     RadioSetChecked(aNotify);
@@ -3009,22 +2935,19 @@ nsHTMLInputElement::WillRemoveFromRadioG
   if (!mForm && !(IsInDoc() && GetParent())) {
     return NS_OK;
   }
 
   //
   // 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
         return NS_OK;
       }
       gotName = PR_TRUE;
     }
 
@@ -3098,19 +3021,17 @@ nsHTMLInputElement::IsHTMLFocusable(PRBo
     *aTabIndex = -1;
   }
 
   if (mType != NS_FORM_INPUT_RADIO) {
     *aIsFocusable = PR_TRUE;
     return PR_FALSE;
   }
 
-  PRBool checked;
-  GetChecked(&checked);
-  if (checked) {
+  if (GetChecked()) {
     // Selected radio buttons are tabbable
     *aIsFocusable = PR_TRUE;
     return PR_FALSE;
   }
 
   // Current radio button is not selected.
   // But make it tabbable if nothing in group is selected.
   nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
--- a/content/html/content/src/nsHTMLLabelElement.cpp
+++ b/content/html/content/src/nsHTMLLabelElement.cpp
@@ -73,17 +73,17 @@ public:
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLLabelElement
   NS_DECL_NSIDOMHTMLLABELELEMENT
 
   // 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();
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               PRBool aCompileEventHandlers);
@@ -324,17 +324,17 @@ nsHTMLLabelElement::PostHandleEvent(nsEv
 
 nsresult
 nsHTMLLabelElement::Reset()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLLabelElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
+nsHTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                       nsIContent* aSubmitElement)
 {
   return NS_OK;
 }
 
 nsresult
 nsHTMLLabelElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
                             const nsAString& aValue, PRBool aNotify)
--- a/content/html/content/src/nsHTMLLegendElement.cpp
+++ b/content/html/content/src/nsHTMLLegendElement.cpp
@@ -70,17 +70,17 @@ public:
   NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
 
   // nsIDOMHTMLLegendElement
   NS_DECL_NSIDOMHTMLLEGENDELEMENT
 
   // 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();
 
   virtual void PerformAccesskey(PRBool aKeyCausesActivation,
                                 PRBool aIsTrustedEvent);
 
   // nsIContent
@@ -279,13 +279,13 @@ void
 nsHTMLLegendElement::PerformAccesskey(PRBool aKeyCausesActivation,
                                       PRBool aIsTrustedEvent)
 {
   // just use the same behaviour as the focus method
   Focus();
 }
 
 NS_IMETHODIMP
-nsHTMLLegendElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
+nsHTMLLegendElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                        nsIContent* aSubmitElement)
 {
   return NS_OK;
 }
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -98,17 +98,17 @@ public:
 
   // Overriden nsIFormControl methods
   NS_IMETHOD_(PRInt32) GetType() const
   {
     return NS_FORM_OBJECT;
   }
 
   NS_IMETHOD Reset();
-  NS_IMETHOD SubmitNamesValues(nsIFormSubmission *aFormSubmission,
+  NS_IMETHOD SubmitNamesValues(nsFormSubmission *aFormSubmission,
                                nsIContent *aSubmitElement);
 
   virtual nsresult DoneAddingChildren(PRBool aHaveNotified);
   virtual PRBool IsDoneAddingChildren();
 
   virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
                                 nsIAtom *aAttribute,
                                 const nsAString &aValue,
@@ -311,17 +311,17 @@ nsHTMLObjectElement::GetDesiredIMEState(
 
 NS_IMETHODIMP
 nsHTMLObjectElement::Reset()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLObjectElement::SubmitNamesValues(nsIFormSubmission *aFormSubmission,
+nsHTMLObjectElement::SubmitNamesValues(nsFormSubmission *aFormSubmission,
                                        nsIContent *aSubmitElement)
 {
   nsAutoString name;
   if (!GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
     // No name, don't submit.
 
     return NS_OK;
   }
@@ -339,17 +339,17 @@ nsHTMLObjectElement::SubmitNamesValues(n
   objFrame->GetPluginInstance(*getter_AddRefs(pi));
   if (!pi)
     return NS_OK;
 
   nsAutoString value;
   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)
 NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Archive, archive)
 NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Border, border)
 NS_IMPL_URI_ATTR_WITH_BASE(nsHTMLObjectElement, Code, code, codebase)
 NS_IMPL_URI_ATTR(nsHTMLObjectElement, CodeBase, codebase)
 NS_IMPL_STRING_ATTR(nsHTMLObjectElement, CodeType, codetype)
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -42,16 +42,17 @@
 #include "nsContentCreatorFunctions.h"
 #include "nsGkAtoms.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
 #include "nsMappedAttributes.h"
 #include "nsIForm.h"
 #include "nsIFormSubmission.h"
+#include "nsIFormProcessor.h"
 
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIOptionElement.h"
 #include "nsIEventStateManager.h"
 #include "nsGUIEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIBoxObject.h"
 #include "nsIDOMNSDocument.h"
@@ -61,16 +62,17 @@
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsIFormControlFrame.h"
 #include "nsIComboboxControlFrame.h"
 #include "nsIListControlFrame.h"
 #include "nsIFrame.h"
 
 #include "nsDOMError.h"
+#include "nsServiceManagerUtils.h"
 #include "nsRuleData.h"
 #include "nsEventDispatcher.h"
 
 NS_IMPL_ISUPPORTS1(nsSelectState, nsSelectState)
 NS_DEFINE_STATIC_IID_ACCESSOR(nsSelectState, NS_SELECT_STATE_IID)
 
 //----------------------------------------------------------------------
 //
@@ -1577,18 +1579,20 @@ nsHTMLSelectElement::Reset()
   // Don't flush, if there's no frame yet it won't care about us being
   // reset even if we forced it to be created now.
   //
   DispatchContentReset();
 
   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;
 
   //
   // Disabled elements don't submit
   //
   PRBool disabled;
@@ -1607,16 +1611,23 @@ nsHTMLSelectElement::SubmitNamesValues(n
   }
 
   //
   // Submit
   //
   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;
     rv = IsOptionDisabled(optIndex, &disabled);
     if (NS_FAILED(rv) || disabled) {
       continue;
     }
 
@@ -1632,17 +1643,25 @@ nsHTMLSelectElement::SubmitNamesValues(n
 
     nsCOMPtr<nsIDOMHTMLOptionElement> optionElement = do_QueryInterface(option);
     NS_ENSURE_TRUE(optionElement, NS_ERROR_UNEXPECTED);
 
     nsAutoString value;
     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;
 }
 
 NS_IMETHODIMP
 nsHTMLSelectElement::GetHasOptGroups(PRBool* aHasGroups)
 {
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -271,17 +271,17 @@ public:
   virtual PRBool IsHTMLFocusable(PRBool *aIsFocusable, PRInt32 *aTabIndex);
   virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
                                  PRBool aNotify);
   virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify, PRBool aMutationEvent = PR_TRUE);
 
   // 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);
 
   // nsISelectElement
   NS_DECL_NSISELECTELEMENT
 
   /**
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -116,17 +116,17 @@ public:
   {
     return nsGenericHTMLElement::GetEditor(aEditor);
   }
   NS_IMETHOD SetUserInput(const nsAString& aInput);
 
   // 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);
 
   // nsITextControlElemet
   NS_IMETHOD TakeTextFrameValue(const nsAString& aValue);
   NS_IMETHOD SetValueChanged(PRBool aValueChanged);
 
@@ -807,17 +807,17 @@ nsHTMLTextAreaElement::Reset()
     rv = SetValue(resetVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   SetValueChanged(PR_FALSE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTextAreaElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
+nsHTMLTextAreaElement::SubmitNamesValues(nsFormSubmission* aFormSubmission,
                                          nsIContent* aSubmitElement)
 {
   nsresult rv = NS_OK;
 
   //
   // Disabled elements don't submit
   //
   PRBool disabled;
@@ -838,17 +838,17 @@ nsHTMLTextAreaElement::SubmitNamesValues
   // Get the value
   //
   nsAutoString value;
   GetValueInternal(value, PR_FALSE);
 
   //
   // Submit
   //
-  rv = aFormSubmission->AddNameValuePair(this, name, value);
+  rv = aFormSubmission->AddNameValuePair(name, value);
 
   return rv;
 }
 
 
 NS_IMETHODIMP
 nsHTMLTextAreaElement::SaveState()
 {
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -214,19 +214,16 @@ pref("accessibility.typeaheadfind.enable
 pref("accessibility.typeaheadfind.prefillwithselection", true);
 
 // use Mac OS X Appearance panel text smoothing setting when rendering text, disabled by default
 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);
 
 pref("toolkit.scrollbox.smoothScroll", true);
 pref("toolkit.scrollbox.scrollIncrement", 20);
 pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150);
 
 // view source
--- a/security/manager/ssl/src/nsKeygenHandler.cpp
+++ b/security/manager/ssl/src/nsKeygenHandler.cpp
@@ -798,53 +798,41 @@ loser:
     return rv;
 }
 
 NS_METHOD 
 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");
-      }
+        keyTypeValue.AssignLiteral("rsa");
+    }
+    
+    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);
+    }
 
-      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);
-      }
+    aElement->GetAttribute(NS_LITERAL_STRING("challenge"), challengeValue);
 
-      res = selectElement->GetAttribute(NS_LITERAL_STRING("challenge"), challengeValue);
-      rv = GetPublicKey(aValue, challengeValue, keyTypeValue, 
-			aValue, keyParamsValue);
-    }
-  }
-
-  return rv; 
+    return GetPublicKey(aValue, challengeValue, keyTypeValue, 
+                        aValue, keyParamsValue);
 } 
 
 NS_METHOD nsKeygenFormProcessor::ProvideContent(const nsAString& aFormType, 
 						nsTArray<nsString>& aContent, 
 						nsAString& aAttribute) 
 { 
   if (Compare(aFormType, NS_LITERAL_STRING("SELECT"), 
     nsCaseInsensitiveStringComparator()) == 0) {