2001-09-25 01:32:19 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
1998-09-02 00:56:01 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* The contents of this file are subject to the Netscape Public License
|
|
|
|
* Version 1.1 (the "License"); you may not use this file except in
|
|
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/NPL/
|
1998-09-02 00:56:01 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
1998-09-02 00:56:01 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Netscape Communications Corporation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
1999-11-06 03:40:37 +00:00
|
|
|
*
|
2001-09-25 01:32:19 +00:00
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the NPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the NPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1999-02-12 17:45:58 +00:00
|
|
|
#include "nsCOMPtr.h"
|
1998-09-23 17:16:51 +00:00
|
|
|
#include "nsIForm.h"
|
|
|
|
#include "nsIFormControl.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
#include "nsIFormSubmission.h"
|
1998-09-02 23:53:16 +00:00
|
|
|
#include "nsIDOMHTMLFormElement.h"
|
1998-09-23 17:16:51 +00:00
|
|
|
#include "nsIDOMNSHTMLFormElement.h"
|
2001-03-22 08:51:52 +00:00
|
|
|
#include "nsIHTMLDocument.h"
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
#include "nsIDOMNSHTMLFormControlList.h"
|
1998-09-02 00:56:01 +00:00
|
|
|
#include "nsIDOMEventReceiver.h"
|
|
|
|
#include "nsIHTMLContent.h"
|
1998-09-02 23:53:16 +00:00
|
|
|
#include "nsGenericHTMLElement.h"
|
1998-09-02 00:56:01 +00:00
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsStyleConsts.h"
|
|
|
|
#include "nsIPresContext.h"
|
1998-09-23 17:16:51 +00:00
|
|
|
#include "nsIDocument.h"
|
2001-11-02 07:40:01 +00:00
|
|
|
#include "nsIPresShell.h"
|
1998-09-23 17:16:51 +00:00
|
|
|
#include "nsIFrame.h"
|
2001-04-17 10:02:11 +00:00
|
|
|
#include "nsIFormControlFrame.h"
|
1999-12-03 09:24:22 +00:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
1999-12-22 01:48:47 +00:00
|
|
|
#include "nsDOMError.h"
|
2001-02-19 12:55:42 +00:00
|
|
|
#include "nsContentUtils.h"
|
2000-04-19 08:45:45 +00:00
|
|
|
#include "nsHashtable.h"
|
2002-03-07 20:53:40 +00:00
|
|
|
#include "nsDoubleHashtable.h"
|
2000-06-01 22:55:19 +00:00
|
|
|
#include "nsContentList.h"
|
2001-07-16 02:40:48 +00:00
|
|
|
#include "nsGUIEvent.h"
|
2002-08-17 05:42:55 +00:00
|
|
|
#include "nsSupportsArray.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
// form submission
|
2001-11-02 07:40:01 +00:00
|
|
|
#include "nsIFormSubmitObserver.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
#include "nsIURI.h"
|
|
|
|
#include "nsIObserverService.h"
|
|
|
|
#include "nsICategoryManager.h"
|
2002-07-18 05:09:10 +00:00
|
|
|
#include "nsCategoryManagerUtils.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
#include "nsISimpleEnumerator.h"
|
|
|
|
#include "nsIDOMWindowInternal.h"
|
|
|
|
#include "nsRange.h"
|
|
|
|
#include "nsIScriptSecurityManager.h"
|
|
|
|
#include "nsNetUtil.h"
|
2002-03-13 06:08:56 +00:00
|
|
|
#include "nsIWebProgress.h"
|
|
|
|
#include "nsIDocShell.h"
|
|
|
|
#include "nsIWebProgressListener.h"
|
|
|
|
#include "nsWeakReference.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
// radio buttons
|
|
|
|
#include "nsIDOMHTMLInputElement.h"
|
|
|
|
#include "nsIRadioControlElement.h"
|
|
|
|
#include "nsIRadioVisitor.h"
|
2002-07-20 23:09:24 +00:00
|
|
|
#include "nsIRadioGroupContainer.h"
|
2000-04-19 07:49:07 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
|
1998-09-02 00:56:01 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
class nsFormControlList;
|
|
|
|
|
|
|
|
// nsHTMLFormElement
|
1998-09-02 00:56:01 +00:00
|
|
|
|
2002-08-06 04:15:10 +00:00
|
|
|
//
|
|
|
|
// PLDHashTable entry for radio button
|
|
|
|
//
|
|
|
|
class PLDHashStringRadioEntry : public PLDHashStringEntry
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PLDHashStringRadioEntry(const void* key) : PLDHashStringEntry(key), mVal(nsnull) { }
|
|
|
|
~PLDHashStringRadioEntry() { }
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> mVal;
|
|
|
|
};
|
|
|
|
|
|
|
|
DECL_DHASH_WRAPPER(nsDoubleHashtableStringRadio, PLDHashStringRadioEntry, nsAString&)
|
|
|
|
DHASH_WRAPPER(nsDoubleHashtableStringRadio, PLDHashStringRadioEntry, nsAString&)
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
class nsHTMLFormElement : public nsGenericHTMLContainerElement,
|
2002-03-13 06:08:56 +00:00
|
|
|
public nsSupportsWeakReference,
|
2000-12-23 10:56:31 +00:00
|
|
|
public nsIDOMHTMLFormElement,
|
1998-10-06 21:41:47 +00:00
|
|
|
public nsIDOMNSHTMLFormElement,
|
2002-03-13 06:08:56 +00:00
|
|
|
public nsIWebProgressListener,
|
2002-07-20 23:09:24 +00:00
|
|
|
public nsIForm,
|
|
|
|
public nsIRadioGroupContainer
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
|
|
|
public:
|
2002-03-07 20:53:40 +00:00
|
|
|
nsHTMLFormElement() :
|
|
|
|
mGeneratingSubmit(PR_FALSE),
|
|
|
|
mGeneratingReset(PR_FALSE),
|
2002-03-13 06:08:56 +00:00
|
|
|
mIsSubmitting(PR_FALSE),
|
2002-12-03 23:06:34 +00:00
|
|
|
mDeferSubmission(PR_FALSE),
|
2002-11-30 00:01:21 +00:00
|
|
|
mPendingSubmission(nsnull),
|
2002-03-13 06:08:56 +00:00
|
|
|
mSubmittingRequest(nsnull) { }
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
virtual ~nsHTMLFormElement();
|
1998-09-02 00:56:01 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
virtual nsresult Init(nsINodeInfo* aNodeInfo);
|
|
|
|
|
1998-09-02 00:56:01 +00:00
|
|
|
// nsISupports
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
1998-09-02 00:56:01 +00:00
|
|
|
|
|
|
|
// nsIDOMNode
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLContainerElement::)
|
1998-09-02 00:56:01 +00:00
|
|
|
|
|
|
|
// nsIDOMElement
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLContainerElement::)
|
1998-09-02 00:56:01 +00:00
|
|
|
|
|
|
|
// nsIDOMHTMLElement
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLContainerElement::)
|
1998-09-02 00:56:01 +00:00
|
|
|
|
1998-09-02 23:53:16 +00:00
|
|
|
// nsIDOMHTMLFormElement
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_DECL_NSIDOMHTMLFORMELEMENT
|
1998-09-02 00:56:01 +00:00
|
|
|
|
1998-10-06 21:41:47 +00:00
|
|
|
// nsIDOMNSHTMLFormElement
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_DECL_NSIDOMNSHTMLFORMELEMENT
|
1999-06-14 22:09:25 +00:00
|
|
|
|
2002-03-13 06:08:56 +00:00
|
|
|
// nsIWebProgressListener
|
|
|
|
NS_DECL_NSIWEBPROGRESSLISTENER
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsIForm
|
|
|
|
NS_IMETHOD AddElement(nsIFormControl* aElement);
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMETHOD AddElementToTable(nsIFormControl* aChild,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName);
|
1998-09-23 17:16:51 +00:00
|
|
|
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
|
|
|
|
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
|
2000-05-30 02:45:55 +00:00
|
|
|
NS_IMETHOD RemoveElement(nsIFormControl* aElement);
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMETHOD RemoveElementFromTable(nsIFormControl* aElement,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName);
|
|
|
|
NS_IMETHOD ResolveName(const nsAString& aName,
|
2002-03-07 20:53:40 +00:00
|
|
|
nsISupports** aReturn);
|
2001-05-30 11:26:21 +00:00
|
|
|
NS_IMETHOD IndexOfControl(nsIFormControl* aControl, PRInt32* aIndex);
|
2002-08-17 05:42:55 +00:00
|
|
|
NS_IMETHOD GetControlEnumerator(nsISimpleEnumerator** aEnumerator);
|
2002-11-30 00:01:21 +00:00
|
|
|
NS_IMETHOD OnSubmitClickBegin();
|
|
|
|
NS_IMETHOD OnSubmitClickEnd();
|
|
|
|
NS_IMETHOD FlushPendingSubmission();
|
|
|
|
NS_IMETHOD ForgetPendingSubmission();
|
2002-07-20 23:09:24 +00:00
|
|
|
|
|
|
|
// nsIRadioGroupContainer
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_IMETHOD SetCurrentRadioButton(const nsAString& aName,
|
|
|
|
nsIDOMHTMLInputElement* aRadio);
|
|
|
|
NS_IMETHOD GetCurrentRadioButton(const nsAString& aName,
|
|
|
|
nsIDOMHTMLInputElement** aRadio);
|
|
|
|
NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor);
|
2002-07-20 23:09:24 +00:00
|
|
|
NS_IMETHOD AddToRadioGroup(const nsAString& aName,
|
|
|
|
nsIFormControl* aRadio);
|
|
|
|
NS_IMETHOD RemoveFromRadioGroup(const nsAString& aName,
|
|
|
|
nsIFormControl* aRadio);
|
2001-11-28 11:00:14 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
// nsIContent
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMETHOD StringToAttribute(nsIAtom* aAttribute,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aValue,
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLValue& aResult);
|
|
|
|
NS_IMETHOD AttributeToString(nsIAtom* aAttribute,
|
|
|
|
const nsHTMLValue& aValue,
|
2002-03-23 23:04:39 +00:00
|
|
|
nsAString& aResult) const;
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent,
|
|
|
|
nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
|
|
|
|
nsEventStatus* aEventStatus);
|
2002-07-16 22:38:51 +00:00
|
|
|
NS_IMETHOD SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
|
|
|
PRBool aCompileEventHandlers);
|
2002-08-20 02:35:39 +00:00
|
|
|
NS_IMETHOD SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|
|
|
const nsAString& aValue, PRBool aNotify);
|
|
|
|
NS_IMETHOD SetAttr(nsINodeInfo* aNodeInfo, const nsAString& aValue,
|
|
|
|
PRBool aNotify) {
|
|
|
|
// This will end up calling the other SetAttr().
|
|
|
|
return nsGenericHTMLContainerElement::SetAttr(aNodeInfo, aValue, aNotify);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Forget all information about the current submission (and the fact that we
|
|
|
|
* are currently submitting at all).
|
|
|
|
*/
|
|
|
|
void ForgetCurrentSubmission();
|
2002-03-07 20:53:40 +00:00
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
/**
|
|
|
|
* Compare two nodes in the same tree (Negative result means a < b, 0 ==,
|
|
|
|
* positive >). This function may fail if the nodes are not in a tree
|
|
|
|
* or are in different trees.
|
|
|
|
*
|
|
|
|
* @param a the first node
|
|
|
|
* @param b the second node
|
|
|
|
* @param retval whether a < b (negative), a == b (0), or a > b (positive)
|
|
|
|
*/
|
|
|
|
static nsresult CompareNodes(nsIDOMNode* a,
|
|
|
|
nsIDOMNode* b,
|
|
|
|
PRInt32* retval);
|
|
|
|
|
1998-09-02 00:56:01 +00:00
|
|
|
protected:
|
2001-04-24 05:18:10 +00:00
|
|
|
nsresult DoSubmitOrReset(nsIPresContext* aPresContext,
|
|
|
|
nsEvent* aEvent,
|
|
|
|
PRInt32 aMessage);
|
2002-02-16 01:19:24 +00:00
|
|
|
nsresult DoReset();
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Submit Helpers
|
|
|
|
//
|
|
|
|
//
|
|
|
|
/**
|
2002-11-30 00:01:21 +00:00
|
|
|
* Attempt to submit (submission might be deferred)
|
|
|
|
* (called by DoSubmitOrReset)
|
2002-02-16 01:19:24 +00:00
|
|
|
*
|
|
|
|
* @param aPresContext the presentation context
|
|
|
|
* @param aEvent the DOM event that was passed to us for the submit
|
|
|
|
*/
|
|
|
|
nsresult DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent);
|
2002-11-30 00:01:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepare the submission object (called by DoSubmit)
|
|
|
|
*
|
|
|
|
* @param aPresContext the presentation context
|
|
|
|
* @param aFormSubmission the submission object
|
|
|
|
* @param aEvent the DOM event that was passed to us for the submit
|
|
|
|
*/
|
|
|
|
nsresult BuildSubmission(nsIPresContext* aPresContext,
|
|
|
|
nsCOMPtr<nsIFormSubmission>& aFormSubmission,
|
|
|
|
nsEvent* aEvent);
|
|
|
|
/**
|
|
|
|
* Perform the submission (called by DoSubmit and FlushPendingSubmission)
|
|
|
|
*
|
|
|
|
* @param aPresContext the presentation context
|
|
|
|
* @param aFormSubmission the submission object
|
|
|
|
*/
|
|
|
|
nsresult SubmitSubmission(nsIPresContext* aPresContext,
|
|
|
|
nsIFormSubmission* aFormSubmission);
|
2002-02-16 01:19:24 +00:00
|
|
|
/**
|
|
|
|
* 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,
|
|
|
|
nsIContent* aSubmitElement);
|
|
|
|
/**
|
|
|
|
* Get the full URL to submit to. Do not submit if the returned URL is null.
|
|
|
|
*
|
|
|
|
* @param aActionURL the full, unadulterated URL you'll be submitting to
|
|
|
|
*/
|
|
|
|
nsresult GetActionURL(nsIURI** aActionURL);
|
|
|
|
/**
|
|
|
|
* Notify any submit observsers 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.
|
|
|
|
*/
|
|
|
|
nsresult NotifySubmitObservers(nsIURI* aActionURL, PRBool* aCancelSubmit);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Data members
|
|
|
|
//
|
2002-08-20 02:35:39 +00:00
|
|
|
/** The list of controls (form.elements as well as stuff not in elements) */
|
2001-11-28 11:00:14 +00:00
|
|
|
nsFormControlList *mControls;
|
2002-08-20 02:35:39 +00:00
|
|
|
/** The currently selected radio button of each group */
|
2002-08-06 04:15:10 +00:00
|
|
|
nsDoubleHashtableStringRadio mSelectedRadioButtons;
|
2002-08-20 02:35:39 +00:00
|
|
|
/** Whether we are currently processing a submit event or not */
|
2001-11-28 11:00:14 +00:00
|
|
|
PRPackedBool mGeneratingSubmit;
|
2002-08-20 02:35:39 +00:00
|
|
|
/** Whether we are currently processing a reset event or not */
|
2001-11-28 11:00:14 +00:00
|
|
|
PRPackedBool mGeneratingReset;
|
2002-08-20 02:35:39 +00:00
|
|
|
/** Whether we are submitting currently */
|
2002-03-13 06:08:56 +00:00
|
|
|
PRPackedBool mIsSubmitting;
|
2002-12-09 19:15:52 +00:00
|
|
|
/** Whether the submission is to be deferred in case a script triggers it */
|
2002-12-03 23:06:34 +00:00
|
|
|
PRPackedBool mDeferSubmission;
|
2002-11-30 00:01:21 +00:00
|
|
|
|
|
|
|
/** The pending submission object */
|
|
|
|
nsCOMPtr<nsIFormSubmission> mPendingSubmission;
|
2002-08-20 02:35:39 +00:00
|
|
|
/** The request currently being submitted */
|
2002-03-13 06:08:56 +00:00
|
|
|
nsCOMPtr<nsIRequest> mSubmittingRequest;
|
2002-08-20 02:35:39 +00:00
|
|
|
/** The web progress object we are currently listening to */
|
|
|
|
nsCOMPtr<nsIWebProgress> mWebProgress;
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
friend class nsFormControlEnumerator;
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
protected:
|
2002-06-04 00:44:04 +00:00
|
|
|
/** Detection of first form to notify observers */
|
2002-02-16 01:19:24 +00:00
|
|
|
static PRBool gFirstFormSubmitted;
|
2002-06-04 00:44:04 +00:00
|
|
|
/** Detection of first password input to initialize the password manager */
|
|
|
|
static PRBool gPasswordManagerInitialized;
|
1998-09-02 00:56:01 +00:00
|
|
|
};
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
PRBool nsHTMLFormElement::gFirstFormSubmitted = PR_FALSE;
|
2002-06-04 00:44:04 +00:00
|
|
|
PRBool nsHTMLFormElement::gPasswordManagerInitialized = PR_FALSE;
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsFormControlList
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
class nsFormControlList : public nsIDOMNSHTMLFormControlList,
|
|
|
|
public nsIDOMHTMLCollection
|
2000-12-23 10:56:31 +00:00
|
|
|
{
|
1998-09-23 17:16:51 +00:00
|
|
|
public:
|
1999-12-22 01:48:47 +00:00
|
|
|
nsFormControlList(nsIDOMHTMLFormElement* aForm);
|
1998-09-23 17:16:51 +00:00
|
|
|
virtual ~nsFormControlList();
|
|
|
|
|
|
|
|
void Clear();
|
1999-12-22 01:48:47 +00:00
|
|
|
void SetForm(nsIDOMHTMLFormElement* aForm);
|
1998-09-23 17:16:51 +00:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
// nsIDOMHTMLCollection interface
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_DECL_NSIDOMHTMLCOLLECTION
|
|
|
|
|
|
|
|
// nsIDOMNSHTMLFormControlList interface
|
|
|
|
NS_DECL_NSIDOMNSHTMLFORMCONTROLLIST
|
1998-09-23 17:16:51 +00:00
|
|
|
|
2002-03-23 23:04:39 +00:00
|
|
|
nsresult GetNamedObject(const nsAString& aName,
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsISupports **aResult);
|
2000-04-19 07:49:07 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
nsresult AddElementToTable(nsIFormControl* aChild,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName);
|
2000-12-23 10:56:31 +00:00
|
|
|
nsresult RemoveElementFromTable(nsIFormControl* aChild,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName);
|
2001-05-30 11:26:21 +00:00
|
|
|
nsresult IndexOfControl(nsIFormControl* aControl,
|
|
|
|
PRInt32* aIndex);
|
2000-04-19 07:49:07 +00:00
|
|
|
|
1999-12-22 01:48:47 +00:00
|
|
|
nsIDOMHTMLFormElement* mForm; // WEAK - the form owns me
|
2000-04-19 07:49:07 +00:00
|
|
|
|
2001-09-06 19:16:03 +00:00
|
|
|
nsAutoVoidArray mElements; // Holds WEAK references - bug 36639
|
2001-03-22 08:51:52 +00:00
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
// This array holds on to all form controls that are not contained
|
2002-02-20 05:51:28 +00:00
|
|
|
// in mElements (form.elements in JS, see ShouldBeInFormControl()).
|
|
|
|
// This is needed to properly clean up the bi-directional references
|
|
|
|
// (both weak and strong) between the form and its form controls.
|
2001-03-22 08:51:52 +00:00
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
nsSmallVoidArray mNotInElements; // Holds WEAK references
|
2001-03-22 08:51:52 +00:00
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
protected:
|
2001-03-22 08:51:52 +00:00
|
|
|
// A map from an ID or NAME attribute to the form control(s), this
|
|
|
|
// hash holds strong references either to the named form control, or
|
|
|
|
// to a list of named form controls, in the case where this hash
|
|
|
|
// holds on to a list of named form controls the list has weak
|
|
|
|
// references to the form control.
|
|
|
|
|
|
|
|
nsSupportsHashtable mNameLookupTable;
|
1998-09-23 17:16:51 +00:00
|
|
|
};
|
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
class nsFormControlEnumerator : public nsISimpleEnumerator {
|
|
|
|
public:
|
|
|
|
nsFormControlEnumerator(nsHTMLFormElement* aForm);
|
2002-11-09 05:11:26 +00:00
|
|
|
virtual ~nsFormControlEnumerator() { };
|
2002-08-17 05:42:55 +00:00
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
2002-08-17 10:30:59 +00:00
|
|
|
NS_DECL_NSISIMPLEENUMERATOR
|
2002-08-17 05:42:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
nsHTMLFormElement* mForm;
|
|
|
|
PRUint32 mElementsIndex;
|
|
|
|
nsSupportsArray mNotInElementsSorted;
|
|
|
|
PRUint32 mNotInElementsIndex;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
static PRBool
|
2002-02-20 05:51:28 +00:00
|
|
|
ShouldBeInElements(nsIFormControl* aFormControl)
|
2001-03-22 08:51:52 +00:00
|
|
|
{
|
|
|
|
// For backwards compatibility (with 4.x and IE) we must not add
|
|
|
|
// <input type=image> elements to the list of form controls in a
|
|
|
|
// form.
|
|
|
|
|
2002-12-18 23:38:09 +00:00
|
|
|
switch (aFormControl->GetType()) {
|
2001-03-22 08:51:52 +00:00
|
|
|
case NS_FORM_BUTTON_BUTTON :
|
|
|
|
case NS_FORM_BUTTON_RESET :
|
|
|
|
case NS_FORM_BUTTON_SUBMIT :
|
|
|
|
case NS_FORM_INPUT_BUTTON :
|
|
|
|
case NS_FORM_INPUT_CHECKBOX :
|
|
|
|
case NS_FORM_INPUT_FILE :
|
|
|
|
case NS_FORM_INPUT_HIDDEN :
|
|
|
|
case NS_FORM_INPUT_RESET :
|
|
|
|
case NS_FORM_INPUT_PASSWORD :
|
|
|
|
case NS_FORM_INPUT_RADIO :
|
|
|
|
case NS_FORM_INPUT_SUBMIT :
|
|
|
|
case NS_FORM_INPUT_TEXT :
|
|
|
|
case NS_FORM_SELECT :
|
|
|
|
case NS_FORM_TEXTAREA :
|
|
|
|
case NS_FORM_FIELDSET :
|
2002-08-06 09:53:58 +00:00
|
|
|
case NS_FORM_OBJECT :
|
2001-03-22 08:51:52 +00:00
|
|
|
return PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// These form control types are not supposed to end up in the
|
|
|
|
// form.elements array
|
|
|
|
//
|
|
|
|
// NS_FORM_INPUT_IMAGE
|
|
|
|
// NS_FORM_LABEL
|
|
|
|
// NS_FORM_OPTION
|
|
|
|
// NS_FORM_OPTGROUP
|
|
|
|
// NS_FORM_LEGEND
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
}
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsHTMLFormElement implementation
|
|
|
|
|
|
|
|
// construction, destruction
|
1998-09-02 00:56:01 +00:00
|
|
|
nsresult
|
2000-05-10 13:13:39 +00:00
|
|
|
NS_NewHTMLFormElement(nsIHTMLContent** aInstancePtrResult,
|
|
|
|
nsINodeInfo *aNodeInfo)
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
2000-05-10 13:13:39 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLFormElement* it = new nsHTMLFormElement();
|
|
|
|
|
|
|
|
if (!it) {
|
1998-09-02 00:56:01 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
nsresult rv = it->Init(aNodeInfo);
|
|
|
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
delete it;
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
*aInstancePtrResult = NS_STATIC_CAST(nsIHTMLContent *, it);
|
|
|
|
NS_ADDREF(*aInstancePtrResult);
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-09-02 00:56:01 +00:00
|
|
|
}
|
|
|
|
|
1999-10-07 00:35:04 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::Init(nsINodeInfo *aNodeInfo)
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
2002-08-20 02:35:39 +00:00
|
|
|
nsresult rv = nsGenericHTMLContainerElement::Init(aNodeInfo);
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
1999-12-22 01:48:47 +00:00
|
|
|
mControls = new nsFormControlList(this);
|
2002-03-07 20:53:40 +00:00
|
|
|
if (!mControls) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
NS_ADDREF(mControls);
|
|
|
|
|
2002-08-06 04:15:10 +00:00
|
|
|
rv = mSelectedRadioButtons.Init(1);
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
return NS_OK;
|
1998-09-02 00:56:01 +00:00
|
|
|
}
|
|
|
|
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLFormElement::~nsHTMLFormElement()
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
2001-03-22 08:51:52 +00:00
|
|
|
if (mControls) {
|
|
|
|
mControls->Clear();
|
|
|
|
mControls->SetForm(nsnull);
|
|
|
|
|
|
|
|
NS_RELEASE(mControls);
|
2000-05-30 02:45:55 +00:00
|
|
|
}
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
1998-09-02 00:56:01 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsISupports
|
1998-09-02 00:56:01 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMPL_ADDREF_INHERITED(nsHTMLFormElement, nsGenericElement)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsHTMLFormElement, nsGenericElement)
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
|
|
|
|
// QueryInterface implementation for nsHTMLFormElement
|
|
|
|
NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLFormElement,
|
|
|
|
nsGenericHTMLContainerElement)
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLFormElement)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFormElement)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIForm)
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
2002-07-20 23:09:24 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIRadioGroupContainer)
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFormElement)
|
|
|
|
NS_HTML_CONTENT_INTERFACE_MAP_END
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
|
|
|
|
// nsIDOMHTMLFormElement
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-02 00:56:01 +00:00
|
|
|
nsresult
|
1998-10-20 17:07:23 +00:00
|
|
|
nsHTMLFormElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
|
|
*aReturn = nsnull;
|
|
|
|
|
|
|
|
nsHTMLFormElement* it = new nsHTMLFormElement();
|
|
|
|
|
|
|
|
if (!it) {
|
1998-09-02 00:56:01 +00:00
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2000-08-18 06:52:31 +00:00
|
|
|
nsCOMPtr<nsIDOMNode> kungFuDeathGrip(it);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
nsresult rv = it->Init(mNodeInfo);
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
CopyInnerTo(this, it, aDeep);
|
|
|
|
|
|
|
|
*aReturn = NS_STATIC_CAST(nsIDOMNode *, it);
|
|
|
|
|
|
|
|
NS_ADDREF(*aReturn);
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-09-02 00:56:01 +00:00
|
|
|
}
|
|
|
|
|
1998-09-02 23:53:16 +00:00
|
|
|
NS_IMETHODIMP
|
1998-09-23 17:16:51 +00:00
|
|
|
nsHTMLFormElement::GetElements(nsIDOMHTMLCollection** aElements)
|
1998-09-02 23:53:16 +00:00
|
|
|
{
|
1998-09-23 17:16:51 +00:00
|
|
|
*aElements = mControls;
|
|
|
|
NS_ADDREF(mControls);
|
1998-09-02 23:53:16 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-08-20 02:35:39 +00:00
|
|
|
nsHTMLFormElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|
|
|
const nsAString& aValue, PRBool aNotify)
|
1998-09-02 23:53:16 +00:00
|
|
|
{
|
2002-08-20 02:35:39 +00:00
|
|
|
if (aName == nsHTMLAtoms::action || aName == nsHTMLAtoms::target) {
|
2002-11-30 00:01:21 +00:00
|
|
|
if (mPendingSubmission) {
|
|
|
|
// aha, there is a pending submission that means we're in
|
|
|
|
// the script and we need to flush it. let's tell it
|
|
|
|
// that the event was ignored to force the flush.
|
|
|
|
// the second argument is not playing a role at all.
|
|
|
|
FlushPendingSubmission();
|
|
|
|
}
|
2002-08-20 02:35:39 +00:00
|
|
|
ForgetCurrentSubmission();
|
|
|
|
}
|
|
|
|
return nsGenericHTMLContainerElement::SetAttr(aNameSpaceID, aName,
|
|
|
|
aValue, aNotify);
|
1998-10-20 17:07:23 +00:00
|
|
|
}
|
|
|
|
|
1998-11-03 01:08:02 +00:00
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLFormElement, AcceptCharset, acceptcharset)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Action, action)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Enctype, enctype)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Method, method)
|
2002-08-20 02:35:39 +00:00
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Name, name)
|
2001-11-02 07:40:01 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsHTMLFormElement::GetTarget(nsAString& aValue)
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
|
|
|
aValue.Truncate();
|
2002-08-20 02:35:39 +00:00
|
|
|
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, aValue);
|
2001-11-02 07:40:01 +00:00
|
|
|
if (rv == NS_CONTENT_ATTR_NOT_THERE) {
|
2002-08-20 02:35:39 +00:00
|
|
|
GetBaseTarget(aValue);
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
2002-08-20 02:35:39 +00:00
|
|
|
return NS_OK;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::SetTarget(const nsAString& aValue)
|
|
|
|
{
|
2002-08-20 02:35:39 +00:00
|
|
|
return SetAttr(kNameSpaceID_None, nsHTMLAtoms::target, aValue, PR_TRUE);
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
1998-09-02 23:53:16 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-23 17:16:51 +00:00
|
|
|
nsHTMLFormElement::Submit()
|
1998-09-02 23:53:16 +00:00
|
|
|
{
|
2002-05-15 01:24:59 +00:00
|
|
|
// Send the submit event
|
2001-04-16 06:36:45 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
|
|
|
if (presContext) {
|
2002-12-14 02:38:17 +00:00
|
|
|
if (mPendingSubmission) {
|
|
|
|
// aha, we have a pending submission that was not flushed
|
|
|
|
// (this happens when form.submit() is called twice)
|
|
|
|
// we have to delete it and build a new one since values
|
|
|
|
// might have changed inbetween (we emulate IE here, that's all)
|
|
|
|
mPendingSubmission = nsnull;
|
|
|
|
}
|
|
|
|
|
2002-12-15 01:27:57 +00:00
|
|
|
rv = DoSubmitOrReset(presContext, nsnull, NS_FORM_SUBMIT);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2001-04-16 06:36:45 +00:00
|
|
|
return rv;
|
1998-09-02 23:53:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-23 17:16:51 +00:00
|
|
|
nsHTMLFormElement::Reset()
|
1998-09-02 23:53:16 +00:00
|
|
|
{
|
2002-05-15 01:24:59 +00:00
|
|
|
// Send the reset event
|
2001-04-16 06:36:45 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
|
|
|
if (presContext) {
|
2002-06-04 00:44:04 +00:00
|
|
|
// Calling HandleDOMEvent() directly so that reset() will work even if
|
|
|
|
// the frame does not exist. This does not have an effect right now, but
|
|
|
|
// If PresShell::HandleEventWithTarget() ever starts to work for elements
|
|
|
|
// without frames, that should be called instead.
|
|
|
|
nsFormEvent event;
|
|
|
|
event.eventStructType = NS_FORM_EVENT;
|
|
|
|
event.message = NS_FORM_RESET;
|
|
|
|
event.originator = nsnull;
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2001-04-16 06:36:45 +00:00
|
|
|
return rv;
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-01-21 21:24:16 +00:00
|
|
|
static nsHTMLValue::EnumTable kFormMethodTable[] = {
|
1998-09-23 17:16:51 +00:00
|
|
|
{ "get", NS_FORM_METHOD_GET },
|
|
|
|
{ "post", NS_FORM_METHOD_POST },
|
|
|
|
{ 0 }
|
|
|
|
};
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-01-21 21:24:16 +00:00
|
|
|
static nsHTMLValue::EnumTable kFormEnctypeTable[] = {
|
1998-09-23 17:16:51 +00:00
|
|
|
{ "multipart/form-data", NS_FORM_ENCTYPE_MULTIPART },
|
|
|
|
{ "application/x-www-form-urlencoded", NS_FORM_ENCTYPE_URLENCODED },
|
2002-07-11 23:32:13 +00:00
|
|
|
{ "text/plain", NS_FORM_ENCTYPE_TEXTPLAIN },
|
1998-09-23 17:16:51 +00:00
|
|
|
{ 0 }
|
|
|
|
};
|
1998-09-02 00:56:01 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLFormElement::StringToAttribute(nsIAtom* aAttribute,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aValue,
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLValue& aResult)
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
1998-09-23 17:16:51 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::method) {
|
2003-01-21 21:24:16 +00:00
|
|
|
if (aResult.ParseEnumValue(aValue, kFormMethodTable)) {
|
1999-07-24 19:55:35 +00:00
|
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
else if (aAttribute == nsHTMLAtoms::enctype) {
|
2003-01-21 21:24:16 +00:00
|
|
|
if (aResult.ParseEnumValue(aValue, kFormEnctypeTable)) {
|
1999-07-24 19:55:35 +00:00
|
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
1998-09-02 00:56:01 +00:00
|
|
|
return NS_CONTENT_ATTR_NOT_THERE;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLFormElement::AttributeToString(nsIAtom* aAttribute,
|
2000-12-23 10:56:31 +00:00
|
|
|
const nsHTMLValue& aValue,
|
2002-03-23 23:04:39 +00:00
|
|
|
nsAString& aResult) const
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
1998-09-23 17:16:51 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::method) {
|
|
|
|
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
|
2003-01-21 21:24:16 +00:00
|
|
|
aValue.EnumValueToString(kFormMethodTable, aResult);
|
1998-09-23 17:16:51 +00:00
|
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aAttribute == nsHTMLAtoms::enctype) {
|
|
|
|
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
|
2003-01-21 21:24:16 +00:00
|
|
|
aValue.EnumValueToString(kFormEnctypeTable, aResult);
|
1998-09-23 17:16:51 +00:00
|
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
|
|
|
}
|
1998-09-02 00:56:01 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
return nsGenericHTMLContainerElement::AttributeToString(aAttribute,
|
|
|
|
aValue, aResult);
|
1998-09-02 00:56:01 +00:00
|
|
|
}
|
|
|
|
|
2002-07-16 22:38:51 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
|
|
|
PRBool aCompileEventHandlers)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIHTMLDocument> oldDocument = do_QueryInterface(mDocument);
|
|
|
|
nsresult rv = nsGenericHTMLContainerElement::SetDocument(aDocument, aDeep,
|
|
|
|
aCompileEventHandlers);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsIHTMLDocument> newDocument = do_QueryInterface(mDocument);
|
|
|
|
if (oldDocument != newDocument) {
|
|
|
|
if (oldDocument) {
|
|
|
|
oldDocument->RemovedForm();
|
2002-08-20 02:35:39 +00:00
|
|
|
ForgetCurrentSubmission();
|
2002-07-16 22:38:51 +00:00
|
|
|
}
|
|
|
|
if (newDocument) {
|
|
|
|
newDocument->AddedForm();
|
|
|
|
}
|
|
|
|
}
|
2002-08-20 02:35:39 +00:00
|
|
|
|
2002-07-16 22:38:51 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-02 00:56:01 +00:00
|
|
|
NS_IMETHODIMP
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLFormElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
2000-12-23 10:56:31 +00:00
|
|
|
nsEvent* aEvent,
|
|
|
|
nsIDOMEvent** aDOMEvent,
|
|
|
|
PRUint32 aFlags,
|
|
|
|
nsEventStatus* aEventStatus)
|
1998-09-02 00:56:01 +00:00
|
|
|
{
|
2001-04-24 05:18:10 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aEvent);
|
|
|
|
|
2002-05-13 17:22:30 +00:00
|
|
|
// If this is the bubble stage, there is a nested form below us which received
|
|
|
|
// a submit event. We do *not* want to handle the submit event for this form
|
|
|
|
// too. So to avert a disaster, we stop the bubbling altogether.
|
|
|
|
if ((aFlags & NS_EVENT_FLAG_BUBBLE) &&
|
|
|
|
(aEvent->message == NS_FORM_RESET || aEvent->message == NS_FORM_SUBMIT)) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-04-24 05:18:10 +00:00
|
|
|
// Ignore recursive calls to submit and reset
|
2002-05-13 17:22:30 +00:00
|
|
|
if (aEvent->message == NS_FORM_SUBMIT) {
|
2001-04-24 05:18:10 +00:00
|
|
|
if (mGeneratingSubmit) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
mGeneratingSubmit = PR_TRUE;
|
2002-12-03 23:06:34 +00:00
|
|
|
|
|
|
|
// let the form know that it needs to defer the submission,
|
|
|
|
// that means that if there are scripted submissions, the
|
|
|
|
// latest one will be deferred until after the exit point of the handler.
|
|
|
|
mDeferSubmission = PR_TRUE;
|
2001-04-24 05:18:10 +00:00
|
|
|
}
|
2002-05-13 17:22:30 +00:00
|
|
|
else if (aEvent->message == NS_FORM_RESET) {
|
2001-04-24 05:18:10 +00:00
|
|
|
if (mGeneratingReset) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
mGeneratingReset = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
2002-12-03 23:06:34 +00:00
|
|
|
|
2002-05-13 17:22:30 +00:00
|
|
|
nsresult rv = nsGenericHTMLContainerElement::HandleDOMEvent(aPresContext,
|
|
|
|
aEvent,
|
|
|
|
aDOMEvent,
|
|
|
|
aFlags,
|
2002-12-03 23:06:34 +00:00
|
|
|
aEventStatus);
|
2002-12-14 02:38:17 +00:00
|
|
|
if (aEvent->message == NS_FORM_SUBMIT) {
|
2002-12-03 23:06:34 +00:00
|
|
|
// let the form know not to defer subsequent submissions
|
|
|
|
mDeferSubmission = PR_FALSE;
|
|
|
|
}
|
2000-08-18 05:18:01 +00:00
|
|
|
|
2002-12-03 23:06:34 +00:00
|
|
|
if (NS_SUCCEEDED(rv) &&
|
2002-11-09 00:25:25 +00:00
|
|
|
!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
|
|
|
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
2000-08-18 05:18:01 +00:00
|
|
|
|
2002-12-03 23:06:34 +00:00
|
|
|
if (*aEventStatus == nsEventStatus_eIgnore) {
|
|
|
|
switch (aEvent->message) {
|
|
|
|
case NS_FORM_RESET:
|
|
|
|
case NS_FORM_SUBMIT:
|
|
|
|
{
|
2002-12-14 02:38:17 +00:00
|
|
|
if (mPendingSubmission && aEvent->message == NS_FORM_SUBMIT) {
|
2002-12-03 23:06:34 +00:00
|
|
|
// tell the form to forget a possible pending submission.
|
|
|
|
// the reason is that the script returned true (the event was
|
|
|
|
// ignored) so if there is a stored submission, it will miss
|
|
|
|
// the name/value of the submitting element, thus we need
|
|
|
|
// to forget it and the form element will build a new one
|
|
|
|
ForgetPendingSubmission();
|
|
|
|
}
|
|
|
|
rv = DoSubmitOrReset(aPresContext, aEvent, aEvent->message);
|
|
|
|
}
|
|
|
|
break;
|
2000-08-18 05:18:01 +00:00
|
|
|
}
|
2002-12-03 23:06:34 +00:00
|
|
|
} else {
|
2002-12-14 02:38:17 +00:00
|
|
|
if (aEvent->message == NS_FORM_SUBMIT) {
|
|
|
|
// tell the form to flush a possible pending submission.
|
|
|
|
// the reason is that the script returned false (the event was
|
|
|
|
// not ignored) so if there is a stored submission, it needs to
|
|
|
|
// be submitted immediatelly.
|
|
|
|
FlushPendingSubmission();
|
|
|
|
}
|
2000-08-18 05:18:01 +00:00
|
|
|
}
|
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2002-05-13 17:22:30 +00:00
|
|
|
if (aEvent->message == NS_FORM_SUBMIT) {
|
2001-04-24 05:18:10 +00:00
|
|
|
mGeneratingSubmit = PR_FALSE;
|
|
|
|
}
|
2002-05-13 17:22:30 +00:00
|
|
|
else if (aEvent->message == NS_FORM_RESET) {
|
2001-04-24 05:18:10 +00:00
|
|
|
mGeneratingReset = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-05-13 17:22:30 +00:00
|
|
|
return rv;
|
1998-09-02 00:56:01 +00:00
|
|
|
}
|
1998-09-23 17:16:51 +00:00
|
|
|
|
2001-04-24 05:18:10 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::DoSubmitOrReset(nsIPresContext* aPresContext,
|
|
|
|
nsEvent* aEvent,
|
2002-02-16 01:19:24 +00:00
|
|
|
PRInt32 aMessage)
|
|
|
|
{
|
2001-04-24 05:18:10 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aPresContext);
|
|
|
|
|
|
|
|
// Make sure the presentation is up-to-date
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
GetDocument(*getter_AddRefs(doc));
|
|
|
|
if (doc) {
|
|
|
|
doc->FlushPendingNotifications();
|
|
|
|
}
|
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
// JBK Don't get form frames anymore - bug 34297
|
2001-04-24 05:18:10 +00:00
|
|
|
|
|
|
|
// Submit or Reset the form
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
if (NS_FORM_RESET == aMessage) {
|
2002-02-16 01:19:24 +00:00
|
|
|
rv = DoReset();
|
2001-04-24 05:18:10 +00:00
|
|
|
}
|
|
|
|
else if (NS_FORM_SUBMIT == aMessage) {
|
2002-02-16 01:19:24 +00:00
|
|
|
rv = DoSubmit(aPresContext, aEvent);
|
2001-04-24 05:18:10 +00:00
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::DoReset()
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
|
|
|
// JBK walk the elements[] array instead of form frame controls - bug 34297
|
|
|
|
PRUint32 numElements;
|
|
|
|
GetElementCount(&numElements);
|
|
|
|
for (PRUint32 elementX = 0; (elementX < numElements); elementX++) {
|
|
|
|
nsCOMPtr<nsIFormControl> controlNode;
|
|
|
|
GetElementAt(elementX, getter_AddRefs(controlNode));
|
|
|
|
if (controlNode) {
|
|
|
|
controlNode->Reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-20 02:35:39 +00:00
|
|
|
#define NS_ENSURE_SUBMIT_SUCCESS(rv) \
|
|
|
|
if (NS_FAILED(rv)) { \
|
|
|
|
ForgetCurrentSubmission(); \
|
|
|
|
return rv; \
|
2002-03-13 06:08:56 +00:00
|
|
|
}
|
2002-11-30 00:01:21 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent)
|
|
|
|
{
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_ASSERTION(!mIsSubmitting, "Either two people are trying to submit or the "
|
|
|
|
"previous submit was not properly cancelled by the DocShell");
|
|
|
|
if (mIsSubmitting) {
|
|
|
|
// 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;
|
2002-08-20 02:35:39 +00:00
|
|
|
NS_ASSERTION(!mWebProgress && !mSubmittingRequest, "Web progress / submitting request should not exist here!");
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
nsCOMPtr<nsIFormSubmission> submission;
|
|
|
|
|
|
|
|
//
|
|
|
|
// prepare the submission object
|
|
|
|
//
|
|
|
|
BuildSubmission(aPresContext, submission, aEvent);
|
|
|
|
|
2002-12-03 23:06:34 +00:00
|
|
|
if(mDeferSubmission) {
|
|
|
|
// we are in an event handler, JS submitted so we have to
|
2002-11-30 00:01:21 +00:00
|
|
|
// defer this submission. let's remember it and return
|
|
|
|
// without submitting
|
|
|
|
mPendingSubmission = submission;
|
|
|
|
// ensure reentrancy
|
|
|
|
mIsSubmitting = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// perform the submission
|
|
|
|
//
|
|
|
|
SubmitSubmission(aPresContext, submission);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::BuildSubmission(nsIPresContext* aPresContext,
|
|
|
|
nsCOMPtr<nsIFormSubmission>& aFormSubmission,
|
|
|
|
nsEvent* aEvent)
|
|
|
|
{
|
2002-12-14 02:38:17 +00:00
|
|
|
NS_ASSERTION(!mPendingSubmission, "tried to build two submissions!");
|
2002-11-30 00:01:21 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
// Get the originating frame (failure is non-fatal)
|
2002-08-20 02:35:39 +00:00
|
|
|
nsIContent *originatingElement = nsnull;
|
2002-02-16 01:19:24 +00:00
|
|
|
if (aEvent) {
|
|
|
|
if (NS_FORM_EVENT == aEvent->eventStructType) {
|
|
|
|
originatingElement = ((nsFormEvent *)aEvent)->originator;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
nsresult rv;
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Get the submission object
|
|
|
|
//
|
2002-11-30 00:01:21 +00:00
|
|
|
rv = GetSubmissionFromForm(this, aPresContext, getter_AddRefs(aFormSubmission));
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Dump the data into the submission object
|
|
|
|
//
|
2002-11-30 00:01:21 +00:00
|
|
|
rv = WalkFormElements(aFormSubmission, originatingElement);
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::SubmitSubmission(nsIPresContext* aPresContext,
|
|
|
|
nsIFormSubmission* aFormSubmission)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Get the action and target
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIURI> actionURI;
|
|
|
|
rv = GetActionURL(getter_AddRefs(actionURI));
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-03-13 06:08:56 +00:00
|
|
|
if (!actionURI) {
|
|
|
|
mIsSubmitting = PR_FALSE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-04-30 23:21:58 +00:00
|
|
|
// javascript URIs are not really submissions; they just call a function.
|
|
|
|
// Also, they may synchronously call submit(), and we want them to be able to
|
|
|
|
// do so while still disallowing other double submissions. (Bug 139798)
|
|
|
|
// Note that any other URI types that are of equivalent type should also be
|
|
|
|
// added here.
|
|
|
|
PRBool schemeIsJavaScript = PR_FALSE;
|
|
|
|
if (NS_SUCCEEDED(actionURI->SchemeIs("javascript", &schemeIsJavaScript)) &&
|
|
|
|
schemeIsJavaScript) {
|
|
|
|
mIsSubmitting = PR_FALSE;
|
|
|
|
}
|
|
|
|
|
2002-03-13 06:08:56 +00:00
|
|
|
nsAutoString target;
|
|
|
|
rv = GetTarget(target);
|
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2002-03-13 06:08:56 +00:00
|
|
|
//
|
|
|
|
// Notify observers of submit
|
|
|
|
//
|
|
|
|
PRBool aCancelSubmit = PR_FALSE;
|
|
|
|
rv = NotifySubmitObservers(actionURI, &aCancelSubmit);
|
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
|
|
|
|
|
|
|
if (aCancelSubmit) {
|
|
|
|
mIsSubmitting = PR_FALSE;
|
|
|
|
return NS_OK;
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
2002-03-13 06:08:56 +00:00
|
|
|
//
|
|
|
|
// Submit
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIDocShell> docShell;
|
2002-11-30 00:01:21 +00:00
|
|
|
rv = aFormSubmission->SubmitTo(actionURI, target, this, aPresContext,
|
|
|
|
getter_AddRefs(docShell),
|
|
|
|
getter_AddRefs(mSubmittingRequest));
|
2002-03-13 06:08:56 +00:00
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
|
|
|
|
2002-03-27 05:45:17 +00:00
|
|
|
// Even if the submit succeeds, it's possible for there to be no docshell
|
|
|
|
// or request; for example, if it's to a named anchor within the same page
|
|
|
|
// the submit will not really do anything.
|
|
|
|
if (docShell) {
|
2002-08-01 18:17:48 +00:00
|
|
|
// If the channel is pending, we have to listen for web progress.
|
|
|
|
PRBool pending = PR_FALSE;
|
|
|
|
mSubmittingRequest->IsPending(&pending);
|
|
|
|
if (pending) {
|
2002-08-20 02:35:39 +00:00
|
|
|
mWebProgress = do_GetInterface(docShell);
|
|
|
|
NS_ASSERTION(mWebProgress, "nsIDocShell not converted to nsIWebProgress!");
|
|
|
|
rv = mWebProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_ALL);
|
2002-08-01 18:17:48 +00:00
|
|
|
NS_ENSURE_SUBMIT_SUCCESS(rv);
|
|
|
|
} else {
|
2002-08-20 02:35:39 +00:00
|
|
|
ForgetCurrentSubmission();
|
2002-08-01 18:17:48 +00:00
|
|
|
}
|
2002-08-20 02:35:39 +00:00
|
|
|
} else {
|
|
|
|
ForgetCurrentSubmission();
|
2002-03-27 05:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL,
|
|
|
|
PRBool* aCancelSubmit)
|
|
|
|
{
|
|
|
|
// If this is the first form, bring alive the first form submit
|
|
|
|
// category observers
|
|
|
|
if (!gFirstFormSubmitted) {
|
|
|
|
gFirstFormSubmitted = PR_TRUE;
|
|
|
|
NS_CreateServicesFromCategory(NS_FIRST_FORMSUBMIT_CATEGORY,
|
|
|
|
nsnull,
|
|
|
|
NS_FIRST_FORMSUBMIT_CATEGORY);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Notify observers that the form is being submitted.
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIObserverService> service =
|
|
|
|
do_GetService("@mozilla.org/observer-service;1", &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> theEnum;
|
|
|
|
rv = service->EnumerateObservers(NS_FORMSUBMIT_SUBJECT,
|
|
|
|
getter_AddRefs(theEnum));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (theEnum) {
|
|
|
|
nsCOMPtr<nsISupports> inst;
|
|
|
|
*aCancelSubmit = PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> window = do_QueryInterface(globalObject);
|
|
|
|
|
|
|
|
PRBool loop = PR_TRUE;
|
|
|
|
while (NS_SUCCEEDED(theEnum->HasMoreElements(&loop)) && loop) {
|
|
|
|
theEnum->GetNext(getter_AddRefs(inst));
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFormSubmitObserver> formSubmitObserver(
|
|
|
|
do_QueryInterface(inst));
|
|
|
|
if (formSubmitObserver) {
|
|
|
|
rv = formSubmitObserver->Notify(this,
|
|
|
|
window,
|
|
|
|
aActionURL,
|
|
|
|
aCancelSubmit);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
if (*aCancelSubmit) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// static
|
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::CompareNodes(nsIDOMNode* a, nsIDOMNode* b, PRInt32* retval)
|
|
|
|
{
|
|
|
|
nsresult rv;
|
|
|
|
|
2002-02-20 05:45:18 +00:00
|
|
|
nsCOMPtr<nsIDOMNode> parentANode;
|
2002-02-16 01:19:24 +00:00
|
|
|
PRInt32 indexA;
|
2002-02-20 05:45:18 +00:00
|
|
|
rv = a->GetParentNode(getter_AddRefs(parentANode));
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-02-20 05:45:18 +00:00
|
|
|
if (!parentANode) {
|
2002-02-16 01:19:24 +00:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
// To get the index, we must turn them both into contents
|
|
|
|
// and do IndexOf(). Ick.
|
2002-02-20 05:45:18 +00:00
|
|
|
nsCOMPtr<nsIContent> parentA(do_QueryInterface(parentANode));
|
2002-02-16 01:19:24 +00:00
|
|
|
nsCOMPtr<nsIContent> contentA(do_QueryInterface(a));
|
2002-02-20 05:45:18 +00:00
|
|
|
if (!parentA || !contentA) {
|
2002-02-16 01:19:24 +00:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
rv = parentA->IndexOf(contentA, indexA);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2002-02-20 05:45:18 +00:00
|
|
|
nsCOMPtr<nsIDOMNode> parentBNode;
|
2002-02-16 01:19:24 +00:00
|
|
|
PRInt32 indexB;
|
2002-02-20 05:45:18 +00:00
|
|
|
rv = b->GetParentNode(getter_AddRefs(parentBNode));
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-02-20 05:45:18 +00:00
|
|
|
if (!parentBNode) {
|
2002-02-16 01:19:24 +00:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
// To get the index, we must turn them both into contents
|
|
|
|
// and do IndexOf(). Ick.
|
2002-02-20 05:45:18 +00:00
|
|
|
nsCOMPtr<nsIContent> parentB(do_QueryInterface(parentBNode));
|
2002-02-16 01:19:24 +00:00
|
|
|
nsCOMPtr<nsIContent> bContent(do_QueryInterface(b));
|
2002-02-20 05:45:18 +00:00
|
|
|
if (!parentB || !bContent) {
|
2002-02-16 01:19:24 +00:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
rv = parentB->IndexOf(bContent, indexB);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2002-02-20 05:45:18 +00:00
|
|
|
*retval = ComparePoints(parentANode, indexA, parentBNode, indexB);
|
2002-02-16 01:19:24 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::WalkFormElements(nsIFormSubmission* aFormSubmission,
|
|
|
|
nsIContent* aSubmitElement)
|
|
|
|
{
|
2002-08-17 05:42:55 +00:00
|
|
|
nsCOMPtr<nsISimpleEnumerator> formControls;
|
|
|
|
nsresult rv = GetControlEnumerator(getter_AddRefs(formControls));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Walk the list of nodes and call SubmitNamesValues() on the controls
|
|
|
|
//
|
2002-08-17 05:42:55 +00:00
|
|
|
PRBool hasMoreElements;
|
|
|
|
nsCOMPtr<nsISupports> controlSupports;
|
|
|
|
nsCOMPtr<nsIFormControl> control;
|
|
|
|
while (NS_SUCCEEDED(formControls->HasMoreElements(&hasMoreElements)) &&
|
|
|
|
hasMoreElements) {
|
|
|
|
rv = formControls->GetNext(getter_AddRefs(controlSupports));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
control = do_QueryInterface(controlSupports);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
// Tell the control to submit its name/value pairs to the submission
|
|
|
|
control->SubmitNamesValues(aFormSubmission, aSubmitElement);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLFormElement::GetActionURL(nsIURI** aActionURL)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
*aActionURL = nsnull;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Grab the URL string
|
|
|
|
//
|
|
|
|
nsAutoString action;
|
|
|
|
GetAction(action);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Form the full action URL
|
|
|
|
//
|
|
|
|
|
|
|
|
// Get the document to form the URL.
|
|
|
|
// We'll also need it later to get the DOM window when notifying form submit
|
|
|
|
// observers (bug 33203)
|
|
|
|
if (!mDocument) {
|
|
|
|
return NS_OK; // No doc means don't submit, see Bug 28988
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get base URL
|
2002-11-07 13:29:34 +00:00
|
|
|
nsCOMPtr<nsIURI> docURL;
|
|
|
|
mDocument->GetDocumentURL(getter_AddRefs(docURL));
|
|
|
|
NS_ENSURE_TRUE(docURL, NS_ERROR_UNEXPECTED);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
// If an action is not specified and we are inside
|
|
|
|
// a HTML document then reload the URL. This makes us
|
|
|
|
// compatible with 4.x browsers.
|
|
|
|
// If we are in some other type of document such as XML or
|
|
|
|
// XUL, do nothing. This prevents undesirable reloading of
|
|
|
|
// a document inside XUL.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURI> actionURL;
|
|
|
|
if (action.IsEmpty()) {
|
|
|
|
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
|
|
|
|
if (!htmlDoc) {
|
|
|
|
// Must be a XML, XUL or other non-HTML document type
|
|
|
|
// so do nothing.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-11-07 13:29:34 +00:00
|
|
|
rv = docURL->Clone(getter_AddRefs(actionURL));
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
} else {
|
2002-11-07 13:29:34 +00:00
|
|
|
nsCOMPtr<nsIURI> baseURL;
|
|
|
|
GetBaseURL(*getter_AddRefs(baseURL));
|
|
|
|
NS_ASSERTION(baseURL, "No Base URL found in Form Submit!\n");
|
|
|
|
if (!baseURL) {
|
|
|
|
return NS_OK; // No base URL -> exit early, see Bug 30721
|
|
|
|
}
|
2002-11-05 03:45:28 +00:00
|
|
|
rv = NS_NewURI(getter_AddRefs(actionURL), action, nsnull, baseURL);
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Verify the URL should be reached
|
|
|
|
//
|
|
|
|
// Get security manager, check to see if access to action URI is allowed.
|
|
|
|
//
|
|
|
|
// XXX This code has not been tested. mailto: does not work in forms.
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIScriptSecurityManager> securityManager =
|
|
|
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
rv = securityManager->CheckLoadURI(docURL, actionURL,
|
|
|
|
nsIScriptSecurityManager::STANDARD);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Assign to the output
|
|
|
|
//
|
|
|
|
*aActionURL = actionURL;
|
|
|
|
NS_ADDREF(*aActionURL);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsIForm
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::GetElementCount(PRUint32* aCount) const
|
|
|
|
{
|
|
|
|
mControls->GetLength(aCount);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLFormElement::GetElementAt(PRInt32 aIndex,
|
|
|
|
nsIFormControl** aFormControl) const
|
2001-12-21 01:10:07 +00:00
|
|
|
{
|
|
|
|
*aFormControl = NS_STATIC_CAST(nsIFormControl *,
|
|
|
|
mControls->mElements.SafeElementAt(aIndex));
|
1998-09-23 17:16:51 +00:00
|
|
|
NS_IF_ADDREF(*aFormControl);
|
2001-12-21 01:10:07 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-04-19 07:49:07 +00:00
|
|
|
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
|
1999-09-13 06:18:09 +00:00
|
|
|
{
|
2001-03-22 08:51:52 +00:00
|
|
|
NS_ENSURE_TRUE(mControls, NS_ERROR_UNEXPECTED);
|
|
|
|
|
2002-02-20 05:51:28 +00:00
|
|
|
if (ShouldBeInElements(aChild)) {
|
2001-03-22 08:51:52 +00:00
|
|
|
// WEAK - don't addref
|
2002-08-17 05:42:55 +00:00
|
|
|
mControls->mElements.AppendElement(aChild);
|
2001-03-22 08:51:52 +00:00
|
|
|
} else {
|
2002-08-17 05:42:55 +00:00
|
|
|
// WEAK - don't addref
|
|
|
|
mControls->mNotInElements.AppendElement(aChild);
|
2001-03-22 08:51:52 +00:00
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
|
|
|
// Notify the radio button it's been added to a group
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
PRInt32 type = aChild->GetType();
|
2002-03-07 20:53:40 +00:00
|
|
|
if (type == NS_FORM_INPUT_RADIO) {
|
|
|
|
nsCOMPtr<nsIRadioControlElement> radio = do_QueryInterface(aChild);
|
|
|
|
nsresult rv = radio->AddedToRadioGroup();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2002-06-04 00:44:04 +00:00
|
|
|
//
|
|
|
|
// If it is a password control, and the password manager has not yet been
|
|
|
|
// initialized, initialize the password manager
|
|
|
|
//
|
|
|
|
if (!gPasswordManagerInitialized && type == NS_FORM_INPUT_PASSWORD) {
|
|
|
|
// Initialize the password manager category
|
|
|
|
gPasswordManagerInitialized = PR_TRUE;
|
|
|
|
NS_CreateServicesFromCategory(NS_PASSWORDMANAGER_CATEGORY,
|
|
|
|
nsnull,
|
|
|
|
NS_PASSWORDMANAGER_CATEGORY);
|
|
|
|
}
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
return NS_OK;
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
NS_IMETHODIMP
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLFormElement::AddElementToTable(nsIFormControl* aChild,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName)
|
2000-04-19 07:49:07 +00:00
|
|
|
{
|
2001-03-22 08:51:52 +00:00
|
|
|
NS_ENSURE_TRUE(mControls, NS_ERROR_UNEXPECTED);
|
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
return mControls->AddElementToTable(aChild, aName);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
NS_IMETHODIMP
|
2000-05-30 02:45:55 +00:00
|
|
|
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild)
|
2000-06-23 14:12:24 +00:00
|
|
|
{
|
2001-03-22 08:51:52 +00:00
|
|
|
NS_ENSURE_TRUE(mControls, NS_ERROR_UNEXPECTED);
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
|
|
|
// Remove it from the radio group if it's a radio button
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if (aChild->GetType() == NS_FORM_INPUT_RADIO) {
|
2002-03-07 20:53:40 +00:00
|
|
|
nsCOMPtr<nsIRadioControlElement> radio = do_QueryInterface(aChild);
|
2002-07-20 23:09:24 +00:00
|
|
|
nsresult rv = radio->WillRemoveFromRadioGroup();
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
}
|
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
if (ShouldBeInElements(aChild)) {
|
|
|
|
mControls->mElements.RemoveElement(aChild);
|
|
|
|
} else {
|
|
|
|
mControls->mNotInElements.RemoveElement(aChild);
|
2002-07-20 23:09:24 +00:00
|
|
|
}
|
|
|
|
|
2000-06-23 14:12:24 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_IMETHODIMP
|
2000-06-23 14:12:24 +00:00
|
|
|
nsHTMLFormElement::RemoveElementFromTable(nsIFormControl* aElement,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName)
|
2000-06-23 14:12:24 +00:00
|
|
|
{
|
2001-03-22 08:51:52 +00:00
|
|
|
NS_ENSURE_TRUE(mControls, NS_ERROR_UNEXPECTED);
|
|
|
|
|
2000-06-23 14:12:24 +00:00
|
|
|
return mControls->RemoveElementFromTable(aElement, aName);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsHTMLFormElement::ResolveName(const nsAString& aName,
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsISupports **aResult)
|
|
|
|
{
|
|
|
|
return mControls->GetNamedObject(aName, aResult);
|
|
|
|
}
|
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnSubmitClickBegin()
|
|
|
|
{
|
2002-12-03 23:06:34 +00:00
|
|
|
mDeferSubmission = PR_TRUE;
|
2002-11-30 00:01:21 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnSubmitClickEnd()
|
|
|
|
{
|
2002-12-03 23:06:34 +00:00
|
|
|
mDeferSubmission = PR_FALSE;
|
2002-11-30 00:01:21 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::FlushPendingSubmission()
|
|
|
|
{
|
|
|
|
if (!mPendingSubmission) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// preform the submission with the stored pending submission
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
|
|
|
SubmitSubmission(presContext, mPendingSubmission);
|
|
|
|
|
|
|
|
// now delete the pending submission object
|
|
|
|
mPendingSubmission = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::ForgetPendingSubmission()
|
|
|
|
{
|
|
|
|
// just delete the pending submission
|
|
|
|
mPendingSubmission = nsnull;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
|
1998-10-06 21:41:47 +00:00
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsHTMLFormElement::GetEncoding(nsAString& aEncoding)
|
1998-10-06 21:41:47 +00:00
|
|
|
{
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
return GetEnctype(aEncoding);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsHTMLFormElement::SetEncoding(const nsAString& aEncoding)
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
{
|
|
|
|
return SetEnctype(aEncoding);
|
1998-10-06 21:41:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-04-18 23:00:58 +00:00
|
|
|
nsHTMLFormElement::GetLength(PRInt32* aLength)
|
1998-10-06 21:41:47 +00:00
|
|
|
{
|
|
|
|
*aLength = mControls->mElements.Count();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-20 02:35:39 +00:00
|
|
|
void
|
|
|
|
nsHTMLFormElement::ForgetCurrentSubmission()
|
|
|
|
{
|
|
|
|
mIsSubmitting = PR_FALSE;
|
|
|
|
mSubmittingRequest = nsnull;
|
|
|
|
if (mWebProgress) {
|
|
|
|
mWebProgress->RemoveProgressListener(this);
|
|
|
|
mWebProgress = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-13 06:08:56 +00:00
|
|
|
// nsIWebProgressListener
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnStateChange(nsIWebProgress* aWebProgress,
|
|
|
|
nsIRequest* aRequest,
|
2002-05-16 20:57:37 +00:00
|
|
|
PRUint32 aStateFlags,
|
2002-03-13 06:08:56 +00:00
|
|
|
PRUint32 aStatus)
|
|
|
|
{
|
|
|
|
// If STATE_STOP is never fired for any reason (redirect? Failed state
|
|
|
|
// change?) the form element will leak. It will be kept around by the
|
|
|
|
// nsIWebProgressListener (assuming it keeps a strong pointer). We will
|
|
|
|
// consequently leak the request.
|
|
|
|
if (aRequest == mSubmittingRequest &&
|
|
|
|
aStateFlags & nsIWebProgressListener::STATE_STOP) {
|
2002-08-20 02:35:39 +00:00
|
|
|
ForgetCurrentSubmission();
|
2002-03-13 06:08:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnProgressChange(nsIWebProgress* aWebProgress,
|
|
|
|
nsIRequest* aRequest,
|
|
|
|
PRInt32 aCurSelfProgress,
|
|
|
|
PRInt32 aMaxSelfProgress,
|
|
|
|
PRInt32 aCurTotalProgress,
|
|
|
|
PRInt32 aMaxTotalProgress)
|
|
|
|
{
|
2002-05-16 20:57:37 +00:00
|
|
|
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
2002-03-13 06:08:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnLocationChange(nsIWebProgress* aWebProgress,
|
|
|
|
nsIRequest* aRequest,
|
|
|
|
nsIURI* location)
|
|
|
|
{
|
2002-05-16 20:57:37 +00:00
|
|
|
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
2002-03-13 06:08:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnStatusChange(nsIWebProgress* aWebProgress,
|
|
|
|
nsIRequest* aRequest,
|
|
|
|
nsresult aStatus,
|
|
|
|
const PRUnichar* aMessage)
|
|
|
|
{
|
2002-05-16 20:57:37 +00:00
|
|
|
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
2002-03-13 06:08:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::OnSecurityChange(nsIWebProgress* aWebProgress,
|
|
|
|
nsIRequest* aRequest,
|
2002-05-16 20:57:37 +00:00
|
|
|
PRUint32 state)
|
2002-03-13 06:08:56 +00:00
|
|
|
{
|
2002-05-16 20:57:37 +00:00
|
|
|
NS_NOTREACHED("notification excluded in AddProgressListener(...)");
|
2002-03-13 06:08:56 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::GetControlEnumerator(nsISimpleEnumerator** aEnum)
|
|
|
|
{
|
|
|
|
*aEnum = new nsFormControlEnumerator(this);
|
|
|
|
NS_ENSURE_TRUE(*aEnum, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
NS_ADDREF(*aEnum);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-11-28 11:00:14 +00:00
|
|
|
NS_IMETHODIMP
|
2001-05-30 11:26:21 +00:00
|
|
|
nsHTMLFormElement::IndexOfControl(nsIFormControl* aControl, PRInt32* aIndex)
|
|
|
|
{
|
|
|
|
NS_ENSURE_TRUE(mControls, NS_ERROR_FAILURE);
|
2001-11-28 11:00:14 +00:00
|
|
|
|
2001-05-30 11:26:21 +00:00
|
|
|
return mControls->IndexOfControl(aControl, aIndex);
|
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::SetCurrentRadioButton(const nsAString& aName,
|
|
|
|
nsIDOMHTMLInputElement* aRadio)
|
|
|
|
{
|
2002-08-06 04:15:10 +00:00
|
|
|
PLDHashStringRadioEntry* entry = mSelectedRadioButtons.AddEntry(aName);
|
|
|
|
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
entry->mVal = aRadio;
|
|
|
|
return NS_OK;
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
1999-10-07 00:35:04 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::GetCurrentRadioButton(const nsAString& aName,
|
|
|
|
nsIDOMHTMLInputElement** aRadio)
|
|
|
|
{
|
2002-08-06 04:15:10 +00:00
|
|
|
PLDHashStringRadioEntry* entry = mSelectedRadioButtons.GetEntry(aName);
|
|
|
|
if (entry) {
|
|
|
|
*aRadio = entry->mVal;
|
|
|
|
NS_IF_ADDREF(*aRadio);
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::WalkRadioGroup(const nsAString& aName,
|
|
|
|
nsIRadioVisitor* aVisitor)
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
PRBool stopIterating = PR_FALSE;
|
|
|
|
|
|
|
|
if (aName.IsEmpty()) {
|
|
|
|
//
|
|
|
|
// XXX If the name is empty, it's not stored in the control list. There
|
|
|
|
// *must* be a more efficient way to do this.
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIFormControl> control;
|
|
|
|
PRUint32 len = 0;
|
|
|
|
GetElementCount(&len);
|
|
|
|
for (PRUint32 i=0; i<len; i++) {
|
|
|
|
GetElementAt(i, getter_AddRefs(control));
|
2002-12-18 23:38:09 +00:00
|
|
|
if (control->GetType() == NS_FORM_INPUT_RADIO) {
|
2002-08-06 04:32:57 +00:00
|
|
|
nsCOMPtr<nsIContent> controlContent(do_QueryInterface(control));
|
|
|
|
if (controlContent) {
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
|
|
|
// XXX This is a particularly frivolous string copy just to determine
|
|
|
|
// if the string is empty or not
|
|
|
|
//
|
|
|
|
nsAutoString name;
|
2002-08-06 04:32:57 +00:00
|
|
|
if (controlContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name,
|
|
|
|
name) != NS_CONTENT_ATTR_NOT_THERE &&
|
|
|
|
name.IsEmpty()) {
|
2002-03-07 20:53:40 +00:00
|
|
|
aVisitor->Visit(control, &stopIterating);
|
|
|
|
if (stopIterating) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//
|
|
|
|
// Get the control / list of controls from the form using form["name"]
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsISupports> item;
|
|
|
|
rv = ResolveName(aName, getter_AddRefs(item));
|
|
|
|
|
|
|
|
if (item) {
|
|
|
|
//
|
|
|
|
// If it's just a lone radio button, then select it.
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(item));
|
|
|
|
if (formControl) {
|
2002-12-18 23:38:09 +00:00
|
|
|
if (formControl->GetType() == NS_FORM_INPUT_RADIO) {
|
2002-03-07 20:53:40 +00:00
|
|
|
aVisitor->Visit(formControl, &stopIterating);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList(do_QueryInterface(item));
|
|
|
|
if (nodeList) {
|
|
|
|
PRUint32 length = 0;
|
|
|
|
nodeList->GetLength(&length);
|
|
|
|
for (PRUint32 i=0; i<length; i++) {
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
nodeList->Item(i, getter_AddRefs(node));
|
|
|
|
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node));
|
|
|
|
if (formControl) {
|
2002-12-18 23:38:09 +00:00
|
|
|
if (formControl->GetType() == NS_FORM_INPUT_RADIO) {
|
2002-03-07 20:53:40 +00:00
|
|
|
aVisitor->Visit(formControl, &stopIterating);
|
|
|
|
if (stopIterating) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::AddToRadioGroup(const nsAString& aName,
|
|
|
|
nsIFormControl* aRadio)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLFormElement::RemoveFromRadioGroup(const nsAString& aName,
|
|
|
|
nsIFormControl* aRadio)
|
|
|
|
{
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
2000-12-23 10:56:31 +00:00
|
|
|
// nsFormControlList implementation, this could go away if there were
|
|
|
|
// a lightweight collection implementation somewhere
|
1998-09-23 17:16:51 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsFormControlList::nsFormControlList(nsIDOMHTMLFormElement* aForm)
|
2001-10-25 03:21:53 +00:00
|
|
|
: mForm(aForm),
|
|
|
|
mNameLookupTable(NS_FORM_CONTROL_LIST_HASHTABLE_SIZE)
|
1998-09-23 17:16:51 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
nsFormControlList::~nsFormControlList()
|
|
|
|
{
|
1999-12-22 01:48:47 +00:00
|
|
|
mForm = nsnull;
|
1998-10-22 23:00:37 +00:00
|
|
|
Clear();
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
|
1999-12-22 01:48:47 +00:00
|
|
|
void
|
|
|
|
nsFormControlList::SetForm(nsIDOMHTMLFormElement* aForm)
|
|
|
|
{
|
|
|
|
mForm = aForm; // WEAK - the form owns me
|
|
|
|
}
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
void
|
|
|
|
nsFormControlList::Clear()
|
|
|
|
{
|
2001-03-22 08:51:52 +00:00
|
|
|
// Null out childrens' pointer to me. No refcounting here
|
2002-08-17 05:42:55 +00:00
|
|
|
PRInt32 i;
|
|
|
|
for (i = mElements.Count()-1; i >= 0; i--) {
|
2001-03-22 08:51:52 +00:00
|
|
|
nsIFormControl* f = NS_STATIC_CAST(nsIFormControl *,
|
2002-08-17 05:42:55 +00:00
|
|
|
mElements.ElementAt(i));
|
2001-03-22 08:51:52 +00:00
|
|
|
if (f) {
|
|
|
|
f->SetForm(nsnull, PR_FALSE);
|
|
|
|
}
|
|
|
|
}
|
2000-06-23 14:12:24 +00:00
|
|
|
mElements.Clear();
|
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
for (i = mNotInElements.Count()-1; i >= 0; i--) {
|
|
|
|
nsIFormControl* f = NS_STATIC_CAST(nsIFormControl*,
|
|
|
|
mNotInElements.ElementAt(i));
|
|
|
|
if (f) {
|
|
|
|
f->SetForm(nsnull, PR_FALSE);
|
|
|
|
}
|
2001-03-22 08:51:52 +00:00
|
|
|
}
|
2002-08-17 05:42:55 +00:00
|
|
|
mNotInElements.Clear();
|
|
|
|
|
|
|
|
mNameLookupTable.Reset();
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
// XPConnect interface list for nsFormControlList
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_INTERFACE_MAP_BEGIN(nsFormControlList)
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLFormControlList)
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMHTMLCollection)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMHTMLCollection)
|
2001-07-11 09:09:30 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(HTMLFormControlCollection)
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_IMPL_ADDREF(nsFormControlList)
|
|
|
|
NS_IMPL_RELEASE(nsFormControlList)
|
1998-09-23 17:16:51 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsIDOMHTMLCollection interface
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsFormControlList::GetLength(PRUint32* aLength)
|
|
|
|
{
|
|
|
|
*aLength = mElements.Count();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsFormControlList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
|
|
|
{
|
2001-12-21 01:10:07 +00:00
|
|
|
nsIFormControl *control = NS_STATIC_CAST(nsIFormControl *,
|
|
|
|
mElements.SafeElementAt(aIndex));
|
1998-09-23 17:16:51 +00:00
|
|
|
if (control) {
|
2001-03-22 08:51:52 +00:00
|
|
|
return CallQueryInterface(control, aReturn);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
*aReturn = nsnull;
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-12-22 01:48:47 +00:00
|
|
|
nsresult
|
2002-03-23 23:04:39 +00:00
|
|
|
nsFormControlList::GetNamedObject(const nsAString& aName,
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsISupports** aResult)
|
1999-12-22 01:48:47 +00:00
|
|
|
{
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
*aResult = nsnull;
|
2000-06-01 22:55:19 +00:00
|
|
|
|
|
|
|
if (!mForm) {
|
|
|
|
// No form, no named objects
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
// Get the hash entry
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsStringKey key(aName);
|
1999-12-22 01:48:47 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
*aResult = mNameLookupTable.Get(&key);
|
1999-12-22 01:48:47 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
return NS_OK;
|
1999-12-22 01:48:47 +00:00
|
|
|
}
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsFormControlList::NamedItem(const nsAString& aName,
|
2000-12-23 10:56:31 +00:00
|
|
|
nsIDOMNode** aReturn)
|
1998-09-23 17:16:51 +00:00
|
|
|
{
|
2000-06-01 22:55:19 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
*aReturn = nsnull;
|
2000-06-01 22:55:19 +00:00
|
|
|
|
|
|
|
nsresult rv = NS_OK;
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
nsStringKey key(aName);
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsCOMPtr<nsISupports> supports(dont_AddRef(mNameLookupTable.Get(&key)));
|
2000-04-19 07:49:07 +00:00
|
|
|
|
2000-06-01 22:55:19 +00:00
|
|
|
if (supports) {
|
|
|
|
// We found something, check if it's a node
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
CallQueryInterface(supports, aReturn);
|
2000-06-01 22:55:19 +00:00
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
if (!*aReturn) {
|
2000-06-01 22:55:19 +00:00
|
|
|
// If not, we check if it's a node list.
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList(do_QueryInterface(supports));
|
|
|
|
NS_WARN_IF_FALSE(nodeList, "Huh, what's going one here?");
|
2000-06-01 22:55:19 +00:00
|
|
|
|
|
|
|
if (nodeList) {
|
|
|
|
// And since we're only asking for one node here, we return the first
|
|
|
|
// one from the list.
|
|
|
|
rv = nodeList->Item(0, aReturn);
|
|
|
|
}
|
|
|
|
}
|
2000-04-19 07:49:07 +00:00
|
|
|
}
|
|
|
|
|
2000-06-01 22:55:19 +00:00
|
|
|
return rv;
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsFormControlList::NamedItem(const nsAString& aName,
|
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 16:46:42 +00:00
|
|
|
nsISupports** aReturn)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aReturn);
|
|
|
|
|
|
|
|
nsStringKey key(aName);
|
|
|
|
|
|
|
|
*aReturn = mNameLookupTable.Get(&key);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
nsresult
|
2000-12-23 10:56:31 +00:00
|
|
|
nsFormControlList::AddElementToTable(nsIFormControl* aChild,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName)
|
2000-04-19 07:49:07 +00:00
|
|
|
{
|
2002-02-20 05:51:28 +00:00
|
|
|
if (!ShouldBeInElements(aChild)) {
|
2001-03-22 08:51:52 +00:00
|
|
|
return NS_OK;
|
2000-06-01 22:55:19 +00:00
|
|
|
}
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsStringKey key(aName);
|
|
|
|
|
2000-06-01 22:55:19 +00:00
|
|
|
nsCOMPtr<nsISupports> supports;
|
2001-03-22 08:51:52 +00:00
|
|
|
supports = dont_AddRef(mNameLookupTable.Get(&key));
|
2000-06-01 22:55:19 +00:00
|
|
|
|
|
|
|
if (!supports) {
|
|
|
|
// No entry found, add the form control
|
|
|
|
nsCOMPtr<nsISupports> child(do_QueryInterface(aChild));
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
mNameLookupTable.Put(&key, child);
|
2000-06-01 22:55:19 +00:00
|
|
|
} else {
|
|
|
|
// Found something in the hash, check its type
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(supports));
|
2000-06-09 22:47:29 +00:00
|
|
|
nsCOMPtr<nsIContent> newChild(do_QueryInterface(aChild));
|
2000-06-01 22:55:19 +00:00
|
|
|
|
|
|
|
if (content) {
|
2000-06-09 22:47:29 +00:00
|
|
|
// Check if the new content is the same as the one we found in the
|
|
|
|
// hash, if it is then we leave it in the hash as it is, this will
|
|
|
|
// happen if a form control has both a name and an id with the same
|
|
|
|
// value
|
|
|
|
if (content == newChild) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-06-01 22:55:19 +00:00
|
|
|
// Found an element, create a list, add the element to the list and put
|
|
|
|
// the list in the hash
|
2002-06-28 01:30:09 +00:00
|
|
|
nsBaseContentList *list = new nsBaseContentList();
|
2000-06-01 22:55:19 +00:00
|
|
|
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
list->AppendElement(content);
|
2000-06-01 22:55:19 +00:00
|
|
|
|
|
|
|
// Add the new child too
|
2001-03-22 08:51:52 +00:00
|
|
|
list->AppendElement(newChild);
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2002-12-11 14:24:49 +00:00
|
|
|
nsCOMPtr<nsISupports> listSupports = do_QueryInterface(list);
|
2001-03-22 08:51:52 +00:00
|
|
|
|
2000-06-01 22:55:19 +00:00
|
|
|
// Replace the element with the list.
|
2001-03-22 08:51:52 +00:00
|
|
|
mNameLookupTable.Put(&key, listSupports);
|
2000-06-01 22:55:19 +00:00
|
|
|
} else {
|
|
|
|
// There's already a list in the hash, add the child to the list
|
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList(do_QueryInterface(supports));
|
|
|
|
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
// Upcast, uggly, but it works!
|
2002-06-28 01:30:09 +00:00
|
|
|
nsBaseContentList *list = NS_STATIC_CAST(nsBaseContentList *,
|
|
|
|
(nsIDOMNodeList *)nodeList.get());
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2000-06-09 22:47:29 +00:00
|
|
|
PRInt32 oldIndex = -1;
|
2002-06-28 01:30:09 +00:00
|
|
|
list->IndexOf(newChild, oldIndex);
|
2000-06-09 22:47:29 +00:00
|
|
|
|
|
|
|
// Add the new child only if it's not in our list already
|
|
|
|
if (oldIndex < 0) {
|
2001-03-22 08:51:52 +00:00
|
|
|
list->AppendElement(newChild);
|
2000-06-09 22:47:29 +00:00
|
|
|
}
|
2000-06-01 22:55:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-05-30 11:26:21 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsFormControlList::IndexOfControl(nsIFormControl* aControl,
|
|
|
|
PRInt32* aIndex)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aIndex);
|
|
|
|
|
|
|
|
*aIndex = mElements.IndexOf(aControl);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-04-19 07:49:07 +00:00
|
|
|
|
|
|
|
nsresult
|
2000-06-23 14:12:24 +00:00
|
|
|
nsFormControlList::RemoveElementFromTable(nsIFormControl* aChild,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aName)
|
2000-05-30 02:45:55 +00:00
|
|
|
{
|
2002-02-20 05:51:28 +00:00
|
|
|
if (!ShouldBeInElements(aChild)) {
|
2001-03-22 08:51:52 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-05-30 02:45:55 +00:00
|
|
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aChild);
|
2001-03-22 08:51:52 +00:00
|
|
|
if (!content) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsStringKey key(aName);
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsCOMPtr<nsISupports> supports(dont_AddRef(mNameLookupTable.Get(&key)));
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
if (!supports)
|
|
|
|
return NS_OK;
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsCOMPtr<nsIFormControl> fctrl(do_QueryInterface(supports));
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
if (fctrl) {
|
|
|
|
// Single element in the hash, just remove it...
|
|
|
|
mNameLookupTable.Remove(&key);
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
nsCOMPtr<nsIDOMNodeList> nodeList(do_QueryInterface(supports));
|
|
|
|
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
// Upcast, uggly, but it works!
|
2002-06-28 01:30:09 +00:00
|
|
|
nsBaseContentList *list = NS_STATIC_CAST(nsBaseContentList *,
|
|
|
|
(nsIDOMNodeList *)nodeList.get());
|
2000-06-01 22:55:19 +00:00
|
|
|
|
2001-03-22 08:51:52 +00:00
|
|
|
list->RemoveElement(content);
|
|
|
|
|
|
|
|
PRUint32 length = 0;
|
|
|
|
list->GetLength(&length);
|
|
|
|
|
|
|
|
if (!length) {
|
|
|
|
// If the list is empty we remove if from our hash, this shouldn't
|
|
|
|
// happen tho
|
|
|
|
mNameLookupTable.Remove(&key);
|
|
|
|
} else if (length == 1) {
|
|
|
|
// Only one element left, replace the list in the hash with the
|
|
|
|
// single element.
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
list->Item(0, getter_AddRefs(node));
|
|
|
|
|
|
|
|
if (node) {
|
|
|
|
nsCOMPtr<nsISupports> tmp(do_QueryInterface(node));
|
|
|
|
mNameLookupTable.Put(&key, tmp.get());
|
2000-06-01 22:55:19 +00:00
|
|
|
}
|
2000-04-19 07:49:07 +00:00
|
|
|
}
|
2001-03-22 08:51:52 +00:00
|
|
|
|
2000-04-19 07:49:07 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
// nsFormControlEnumerator
|
|
|
|
NS_IMPL_ISUPPORTS1(nsFormControlEnumerator, nsISimpleEnumerator);
|
|
|
|
|
|
|
|
nsFormControlEnumerator::nsFormControlEnumerator(nsHTMLFormElement* aForm)
|
|
|
|
: mForm(aForm), mElementsIndex(0), mNotInElementsIndex(0)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Create the sorted mNotInElementsSorted array
|
|
|
|
PRInt32 len = aForm->mControls->mNotInElements.Count();
|
|
|
|
for (PRInt32 indexToAdd=0; indexToAdd < len; indexToAdd++) {
|
|
|
|
// Ref doesn't need to be strong, don't bother making it so
|
|
|
|
nsIFormControl* controlToAdd = NS_STATIC_CAST(nsIFormControl*,
|
|
|
|
aForm->mControls->mNotInElements.ElementAt(indexToAdd));
|
|
|
|
|
|
|
|
// Go through the array and insert the element at the first place where
|
|
|
|
// it is less than the element already in the array
|
|
|
|
nsCOMPtr<nsIDOMNode> controlToAddNode = do_QueryInterface(controlToAdd);
|
|
|
|
nsCOMPtr<nsIDOMNode> existingNode;
|
|
|
|
PRBool inserted = PR_FALSE;
|
|
|
|
// Loop over all elements backwards (from indexToAdd to 0)
|
|
|
|
// indexToAdd is equal to the array length because we've been adding to it
|
|
|
|
// constantly
|
|
|
|
PRUint32 i = indexToAdd;
|
|
|
|
while (i > 0) {
|
|
|
|
i--;
|
|
|
|
existingNode = do_QueryElementAt(&mNotInElementsSorted, i);
|
|
|
|
PRInt32 comparison;
|
|
|
|
if (NS_FAILED(nsHTMLFormElement::CompareNodes(controlToAddNode,
|
|
|
|
existingNode,
|
|
|
|
&comparison))) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (comparison > 0) {
|
|
|
|
if (mNotInElementsSorted.InsertElementAt(controlToAdd, i+1)) {
|
|
|
|
inserted = PR_TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If it wasn't inserted yet, it is greater than everything in the array
|
|
|
|
// and must be appended.
|
|
|
|
if (!inserted) {
|
|
|
|
if (!mNotInElementsSorted.InsertElementAt(controlToAdd,0)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsFormControlEnumerator::HasMoreElements(PRBool* aHasMoreElements)
|
|
|
|
{
|
|
|
|
PRUint32 len;
|
|
|
|
mForm->GetElementCount(&len);
|
|
|
|
if (mElementsIndex < len) {
|
|
|
|
*aHasMoreElements = PR_TRUE;
|
|
|
|
} else {
|
|
|
|
PRUint32 notInElementsLen;
|
|
|
|
mNotInElementsSorted.Count(¬InElementsLen);
|
|
|
|
*aHasMoreElements = mNotInElementsIndex < notInElementsLen;
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsFormControlEnumerator::GetNext(nsISupports** aNext)
|
|
|
|
{
|
|
|
|
// Holds the current form control in form.elements
|
|
|
|
nsCOMPtr<nsIFormControl> formControl;
|
|
|
|
// First get the form control in form.elements
|
|
|
|
PRUint32 len;
|
|
|
|
mForm->GetElementCount(&len);
|
|
|
|
if (mElementsIndex < len) {
|
|
|
|
mForm->GetElementAt(mElementsIndex, getter_AddRefs(formControl));
|
|
|
|
}
|
|
|
|
// If there are still controls in mNotInElementsSorted, determine whether said
|
|
|
|
// control is before the current control in the array, and if so, choose it
|
|
|
|
// instead
|
|
|
|
PRUint32 notInElementsLen;
|
|
|
|
mNotInElementsSorted.Count(¬InElementsLen);
|
|
|
|
if (mNotInElementsIndex < notInElementsLen) {
|
|
|
|
// Get the not-in-elements control - weak ref
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFormControl> formControl2 =
|
|
|
|
do_QueryElementAt(&mNotInElementsSorted, mNotInElementsIndex);
|
|
|
|
|
|
|
|
if (formControl) {
|
|
|
|
// Both form controls are there. We have to compare them and see which
|
|
|
|
// one we need to choose right now.
|
|
|
|
nsCOMPtr<nsIDOMNode> dom1 = do_QueryInterface(formControl);
|
|
|
|
nsCOMPtr<nsIDOMNode> dom2 = do_QueryInterface(formControl2);
|
|
|
|
PRInt32 comparison = 0;
|
|
|
|
nsresult rv = nsHTMLFormElement::CompareNodes(dom1, dom2, &comparison);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (comparison < 0) {
|
|
|
|
*aNext = formControl;
|
|
|
|
mElementsIndex++;
|
|
|
|
} else {
|
|
|
|
*aNext = formControl2;
|
|
|
|
mNotInElementsIndex++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*aNext = formControl2;
|
|
|
|
mNotInElementsIndex++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*aNext = formControl;
|
|
|
|
mElementsIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IF_ADDREF(*aNext);
|
|
|
|
return NS_OK;
|
|
|
|
}
|