2003-03-19 03:47:09 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2001-09-25 01:32:19 +00:00
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
2004-04-17 21:52:36 +00:00
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
1998-09-01 01:27:08 +00:00
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
1998-09-01 01:27:08 +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-01 01:27:08 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code.
|
|
|
|
*
|
2004-04-17 21:52:36 +00:00
|
|
|
* The Initial Developer of the Original Code is
|
2001-09-25 01:32:19 +00:00
|
|
|
* 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):
|
2000-02-02 22:24:56 +00:00
|
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
2001-09-25 01:32:19 +00:00
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
2004-04-17 21:52:36 +00:00
|
|
|
* either of 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"),
|
2001-09-25 01:32:19 +00:00
|
|
|
* 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
|
2004-04-17 21:52:36 +00:00
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
2001-09-25 01:32:19 +00:00
|
|
|
* 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
|
2004-04-17 21:52:36 +00:00
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
2001-09-25 01:32:19 +00:00
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
1999-10-07 00:35:04 +00:00
|
|
|
#include "nsCOMPtr.h"
|
1998-09-01 01:27:08 +00:00
|
|
|
#include "nsIDOMHTMLInputElement.h"
|
1999-12-01 15:12:49 +00:00
|
|
|
#include "nsIDOMNSHTMLInputElement.h"
|
2001-11-02 07:40:01 +00:00
|
|
|
#include "nsITextControlElement.h"
|
2002-03-07 20:53:40 +00:00
|
|
|
#include "nsIRadioControlElement.h"
|
|
|
|
#include "nsIRadioVisitor.h"
|
2002-12-17 23:38:04 +00:00
|
|
|
#include "nsIPhonetic.h"
|
2002-03-07 20:53:40 +00:00
|
|
|
|
1999-12-01 15:12:49 +00:00
|
|
|
#include "nsIControllers.h"
|
2001-04-18 01:41:20 +00:00
|
|
|
#include "nsIFocusController.h"
|
|
|
|
#include "nsPIDOMWindow.h"
|
|
|
|
#include "nsIScriptGlobalObject.h"
|
2001-02-22 03:01:34 +00:00
|
|
|
#include "nsContentCID.h"
|
1999-12-01 15:12:49 +00:00
|
|
|
#include "nsIComponentManager.h"
|
1998-09-23 17:16:51 +00:00
|
|
|
#include "nsIDOMHTMLFormElement.h"
|
1998-09-01 01:27:08 +00:00
|
|
|
#include "nsIDOMEventReceiver.h"
|
|
|
|
#include "nsIHTMLContent.h"
|
1998-09-02 23:53:16 +00:00
|
|
|
#include "nsGenericHTMLElement.h"
|
1998-09-01 01:27:08 +00:00
|
|
|
#include "nsHTMLAtoms.h"
|
|
|
|
#include "nsStyleConsts.h"
|
|
|
|
#include "nsIPresContext.h"
|
2004-01-26 19:22:05 +00:00
|
|
|
#include "nsMappedAttributes.h"
|
1998-09-23 17:16:51 +00:00
|
|
|
#include "nsIFormControl.h"
|
|
|
|
#include "nsIForm.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
#include "nsIFormSubmission.h"
|
2002-07-26 20:57:24 +00:00
|
|
|
#include "nsITextControlFrame.h"
|
|
|
|
#include "nsIRadioControlFrame.h"
|
1999-01-26 23:43:52 +00:00
|
|
|
#include "nsIDocument.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
#include "nsIFormControlFrame.h"
|
|
|
|
#include "nsIFrame.h"
|
1999-03-02 19:19:24 +00:00
|
|
|
#include "nsIEventStateManager.h"
|
2000-02-23 22:34:40 +00:00
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIScriptSecurityManager.h"
|
|
|
|
#include "nsDOMError.h"
|
2000-06-21 00:23:28 +00:00
|
|
|
#include "nsIPrivateDOMEvent.h"
|
2000-07-14 23:20:48 +00:00
|
|
|
#include "nsIEditor.h"
|
2001-07-16 02:40:48 +00:00
|
|
|
#include "nsGUIEvent.h"
|
1998-09-01 01:27:08 +00:00
|
|
|
|
2000-01-14 09:28:54 +00:00
|
|
|
#include "nsIPresState.h"
|
2003-11-10 05:52:29 +00:00
|
|
|
#include "nsLayoutErrors.h"
|
2000-05-04 13:57:35 +00:00
|
|
|
#include "nsIDOMEvent.h"
|
2001-12-06 06:57:03 +00:00
|
|
|
#include "nsIDOMNSEvent.h"
|
2000-02-15 23:02:55 +00:00
|
|
|
#include "nsIDOMNodeList.h"
|
|
|
|
#include "nsIDOMHTMLCollection.h"
|
2000-08-02 22:06:37 +00:00
|
|
|
#include "nsICheckboxControlFrame.h"
|
2001-11-02 07:40:01 +00:00
|
|
|
#include "nsIImageControlFrame.h"
|
|
|
|
#include "nsLinebreakConverter.h" //to strip out carriage returns
|
|
|
|
#include "nsReadableUtils.h"
|
2002-09-16 06:00:08 +00:00
|
|
|
#include "nsUnicharUtils.h"
|
2000-01-14 09:28:54 +00:00
|
|
|
|
2001-05-11 21:11:38 +00:00
|
|
|
#include "nsIDOMMutationEvent.h"
|
|
|
|
#include "nsIDOMEventReceiver.h"
|
|
|
|
#include "nsMutationEvent.h"
|
|
|
|
|
2001-10-24 00:01:09 +00:00
|
|
|
#include "nsRuleNode.h"
|
2001-05-31 22:19:43 +00:00
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
// input type=radio
|
|
|
|
#include "nsIRadioControlFrame.h"
|
|
|
|
#include "nsIRadioGroupContainer.h"
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
// input type=file
|
|
|
|
#include "nsIMIMEService.h"
|
|
|
|
#include "nsCExternalHandlerService.h"
|
|
|
|
#include "nsIFile.h"
|
|
|
|
#include "nsILocalFile.h"
|
|
|
|
#include "nsIFileStreams.h"
|
2002-09-16 06:00:08 +00:00
|
|
|
#include "nsNetUtil.h"
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2003-03-19 03:47:09 +00:00
|
|
|
// input type=image
|
|
|
|
#include "nsImageLoadingContent.h"
|
2003-05-12 07:11:16 +00:00
|
|
|
#include "nsIDOMWindowInternal.h"
|
2003-03-19 03:47:09 +00:00
|
|
|
|
1998-09-01 01:27:08 +00:00
|
|
|
// XXX align=left, hspace, vspace, border? other nav4 attrs
|
|
|
|
|
2000-09-09 05:46:14 +00:00
|
|
|
static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
|
1998-09-01 01:27:08 +00:00
|
|
|
|
2002-02-08 18:23:47 +00:00
|
|
|
//
|
|
|
|
// Accessors for mBitField
|
|
|
|
//
|
2003-11-10 05:52:29 +00:00
|
|
|
#define BF_DISABLED_CHANGED 0
|
2002-02-08 18:23:47 +00:00
|
|
|
#define BF_HANDLING_CLICK 1
|
|
|
|
#define BF_VALUE_CHANGED 2
|
|
|
|
#define BF_CHECKED_CHANGED 3
|
|
|
|
#define BF_CHECKED 4
|
2002-02-20 03:18:14 +00:00
|
|
|
#define BF_HANDLING_SELECT_EVENT 5
|
2002-03-31 10:14:01 +00:00
|
|
|
#define BF_SHOULD_INIT_CHECKED 6
|
|
|
|
#define BF_PARSER_CREATING 7
|
2004-04-30 23:55:16 +00:00
|
|
|
#define BF_IN_INTERNAL_ACTIVATE 8
|
|
|
|
#define BF_CHECKED_IS_TOGGLED 9
|
2002-02-08 18:23:47 +00:00
|
|
|
|
|
|
|
#define GET_BOOLBIT(bitfield, field) (((bitfield) & (0x01 << (field))) \
|
|
|
|
? PR_TRUE : PR_FALSE)
|
|
|
|
#define SET_BOOLBIT(bitfield, field, b) ((b) \
|
|
|
|
? ((bitfield) |= (0x01 << (field))) \
|
|
|
|
: ((bitfield) &= ~(0x01 << (field))))
|
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
class nsHTMLInputElement : public nsGenericHTMLFormElement,
|
2003-03-19 03:47:09 +00:00
|
|
|
public nsImageLoadingContent,
|
2000-12-23 10:56:31 +00:00
|
|
|
public nsIDOMHTMLInputElement,
|
2001-11-02 07:40:01 +00:00
|
|
|
public nsIDOMNSHTMLInputElement,
|
2002-03-07 20:53:40 +00:00
|
|
|
public nsITextControlElement,
|
2002-12-17 23:38:04 +00:00
|
|
|
public nsIRadioControlElement,
|
|
|
|
public nsIPhonetic
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
|
|
|
public:
|
2004-05-18 20:58:12 +00:00
|
|
|
nsHTMLInputElement(nsINodeInfo *aNodeInfo, PRBool aFromParser);
|
1999-02-12 17:45:58 +00:00
|
|
|
virtual ~nsHTMLInputElement();
|
1998-09-01 01:27:08 +00:00
|
|
|
|
|
|
|
// nsISupports
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
1998-09-01 01:27:08 +00:00
|
|
|
|
|
|
|
// nsIDOMNode
|
2004-02-10 19:36:43 +00:00
|
|
|
NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLFormElement::)
|
1998-09-01 01:27:08 +00:00
|
|
|
|
|
|
|
// nsIDOMElement
|
2004-02-10 19:36:43 +00:00
|
|
|
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
|
1999-10-30 16:30:33 +00:00
|
|
|
|
1998-09-01 01:27:08 +00:00
|
|
|
// nsIDOMHTMLElement
|
2004-02-10 19:36:43 +00:00
|
|
|
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
|
1998-09-01 01:27:08 +00:00
|
|
|
|
|
|
|
// nsIDOMHTMLInputElement
|
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_NSIDOMHTMLINPUTELEMENT
|
1999-12-01 15:12:49 +00:00
|
|
|
|
|
|
|
// nsIDOMNSHTMLInputElement
|
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_NSIDOMNSHTMLINPUTELEMENT
|
1999-12-01 15:12:49 +00:00
|
|
|
|
2002-12-17 23:38:04 +00:00
|
|
|
// nsIPhonetic
|
|
|
|
NS_DECL_NSIPHONETIC
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
// Overriden nsIFormControl methods
|
2002-12-18 23:38:09 +00:00
|
|
|
NS_IMETHOD_(PRInt32) GetType() { return mType; }
|
2001-11-02 07:40:01 +00:00
|
|
|
NS_IMETHOD Reset();
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
|
|
|
|
nsIContent* aSubmitElement);
|
2002-03-31 10:14:01 +00:00
|
|
|
NS_IMETHOD SaveState();
|
|
|
|
NS_IMETHOD RestoreState(nsIPresState* aState);
|
2004-02-11 21:31:53 +00:00
|
|
|
virtual PRBool AllowDrop();
|
2001-11-02 07:40:01 +00:00
|
|
|
|
|
|
|
// nsIContent
|
2004-01-09 23:54:21 +00:00
|
|
|
virtual void SetFocus(nsIPresContext* aPresContext);
|
|
|
|
virtual void RemoveFocus(nsIPresContext* aPresContext);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2004-03-04 02:06:28 +00:00
|
|
|
virtual PRBool ParseAttribute(nsIAtom* aAttribute,
|
|
|
|
const nsAString& aValue,
|
|
|
|
nsAttrValue& aResult);
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMETHOD AttributeToString(nsIAtom* aAttribute,
|
|
|
|
const nsHTMLValue& aValue,
|
2002-03-23 23:04:39 +00:00
|
|
|
nsAString& aResult) const;
|
2003-07-11 21:16:12 +00:00
|
|
|
NS_IMETHOD GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|
|
|
PRInt32 aModType,
|
|
|
|
nsChangeHint& aHint) const;
|
2004-02-25 21:04:50 +00:00
|
|
|
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
2001-05-31 22:19:43 +00:00
|
|
|
NS_IMETHOD GetAttributeMappingFunction(nsMapRuleToAttributesFunc& aMapRuleFunc) const;
|
2004-01-09 23:54:21 +00:00
|
|
|
virtual nsresult HandleDOMEvent(nsIPresContext* aPresContext,
|
|
|
|
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
|
|
|
PRUint32 aFlags,
|
|
|
|
nsEventStatus* aEventStatus);
|
|
|
|
virtual void SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
|
|
|
PRBool aCompileEventHandlers);
|
|
|
|
virtual void SetParent(nsIContent* aParent);
|
|
|
|
|
2004-01-15 17:07:27 +00:00
|
|
|
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|
|
|
const nsAString& aValue, PRBool aNotify)
|
|
|
|
{
|
|
|
|
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
|
|
|
}
|
2004-01-09 23:54:21 +00:00
|
|
|
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
2004-01-15 17:07:27 +00:00
|
|
|
nsIAtom* aPrefix, const nsAString& aValue,
|
|
|
|
PRBool aNotify)
|
2004-01-09 23:54:21 +00:00
|
|
|
{
|
2002-03-07 20:53:40 +00:00
|
|
|
BeforeSetAttr(aNameSpaceID, aName, &aValue, aNotify);
|
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName,
|
|
|
|
aPrefix, aValue, aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
|
|
|
|
AfterSetAttr(aNameSpaceID, aName, &aValue, aNotify);
|
2001-11-05 06:50:21 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
|
|
|
PRBool aNotify)
|
|
|
|
{
|
2002-03-07 20:53:40 +00:00
|
|
|
BeforeSetAttr(aNameSpaceID, aAttribute, nsnull, aNotify);
|
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, aAttribute,
|
2001-11-05 06:50:21 +00:00
|
|
|
aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
|
|
|
|
AfterSetAttr(aNameSpaceID, aAttribute, nsnull, aNotify);
|
2001-11-05 06:50:21 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
virtual void DoneCreatingElement();
|
2002-03-31 10:14:01 +00:00
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
// nsITextControlElement
|
2002-12-16 23:49:16 +00:00
|
|
|
NS_IMETHOD TakeTextFrameValue(const nsAString& aValue);
|
2001-11-05 06:50:21 +00:00
|
|
|
NS_IMETHOD SetValueChanged(PRBool aValueChanged);
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
// nsIRadioControlElement
|
2004-01-21 04:28:57 +00:00
|
|
|
NS_IMETHOD RadioSetChecked(PRBool aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_IMETHOD SetCheckedChanged(PRBool aCheckedChanged);
|
|
|
|
NS_IMETHOD SetCheckedChangedInternal(PRBool aCheckedChanged);
|
|
|
|
NS_IMETHOD GetCheckedChanged(PRBool* aCheckedChanged);
|
2004-01-21 04:28:57 +00:00
|
|
|
NS_IMETHOD AddedToRadioGroup(PRBool aNotify = PR_TRUE);
|
2002-07-20 23:09:24 +00:00
|
|
|
NS_IMETHOD WillRemoveFromRadioGroup();
|
2002-03-07 20:53:40 +00:00
|
|
|
|
2000-04-13 05:15:59 +00:00
|
|
|
protected:
|
2000-11-28 03:41:50 +00:00
|
|
|
// Helper method
|
2002-12-16 23:49:16 +00:00
|
|
|
nsresult SetValueInternal(const nsAString& aValue,
|
|
|
|
nsITextControlFrame* aFrame);
|
2000-04-13 05:15:59 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
nsresult GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd);
|
2001-05-11 21:11:38 +00:00
|
|
|
//Helper method
|
2001-08-17 03:13:07 +00:00
|
|
|
#ifdef ACCESSIBILITY
|
2001-05-11 21:11:38 +00:00
|
|
|
nsresult FireEventForAccessibility(nsIPresContext* aPresContext,
|
2003-03-19 03:47:09 +00:00
|
|
|
const nsAString& aEventType);
|
2001-08-17 03:13:07 +00:00
|
|
|
#endif
|
2000-04-13 05:15:59 +00:00
|
|
|
|
2002-08-06 04:32:57 +00:00
|
|
|
/**
|
|
|
|
* Get the name if it exists and return whether it did exist
|
|
|
|
* @param aName the name returned [OUT]
|
|
|
|
* @param true if the name existed, false if not
|
|
|
|
*/
|
|
|
|
PRBool GetNameIfExists(nsAString& aName) {
|
|
|
|
return GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, aName) !=
|
|
|
|
NS_CONTENT_ATTR_NOT_THERE;
|
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
/**
|
|
|
|
* Called when an attribute is about to be changed
|
|
|
|
*/
|
|
|
|
void BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString* aValue, PRBool aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
/**
|
|
|
|
* Called when an attribute has just been changed
|
|
|
|
*/
|
|
|
|
void AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString* aValue, PRBool aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
void SelectAll(nsIPresContext* aPresContext);
|
|
|
|
PRBool IsImage() const
|
|
|
|
{
|
|
|
|
nsAutoString tmp;
|
1998-11-23 19:33:22 +00:00
|
|
|
|
2002-05-20 22:47:02 +00:00
|
|
|
GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, tmp);
|
2000-04-19 07:49:07 +00:00
|
|
|
|
2004-06-17 00:13:25 +00:00
|
|
|
return tmp.LowerCaseEqualsLiteral("image");
|
1998-11-23 19:33:22 +00:00
|
|
|
}
|
2000-08-01 21:40:38 +00:00
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
/**
|
|
|
|
* Fire the onChange event
|
|
|
|
*/
|
2002-01-24 19:04:55 +00:00
|
|
|
void FireOnChange();
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
/**
|
|
|
|
* Visit a the group of radio buttons this radio belongs to
|
|
|
|
* @param aVisitor the visitor to visit with
|
|
|
|
*/
|
2002-03-07 20:53:40 +00:00
|
|
|
nsresult VisitGroup(nsIRadioVisitor* aVisitor);
|
|
|
|
|
2004-01-21 04:28:57 +00:00
|
|
|
/**
|
|
|
|
* Do all the work that |SetChecked| does (radio button handling, etc.), but
|
|
|
|
* take an |aNotify| parameter.
|
|
|
|
*/
|
|
|
|
nsresult DoSetChecked(PRBool aValue, PRBool aNotify = PR_TRUE);
|
|
|
|
|
2002-04-03 05:09:27 +00:00
|
|
|
/**
|
|
|
|
* Actually set checked and notify the frame of the change.
|
|
|
|
* @param aValue the value of checked to set
|
|
|
|
*/
|
2004-01-21 04:28:57 +00:00
|
|
|
nsresult SetCheckedInternal(PRBool aValue, PRBool aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
/**
|
|
|
|
* Get the radio group container for this button (form or document)
|
|
|
|
* @return the radio group container (or null if no form or document)
|
|
|
|
*/
|
|
|
|
already_AddRefed<nsIRadioGroupContainer> GetRadioGroupContainer();
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2004-01-05 23:39:50 +00:00
|
|
|
/**
|
|
|
|
* MaybeSubmitForm looks for a submit input or a single text control
|
|
|
|
* and submits the form if either is present.
|
|
|
|
*/
|
|
|
|
nsresult MaybeSubmitForm(nsIPresContext* aPresContext);
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
nsCOMPtr<nsIControllers> mControllers;
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
/**
|
|
|
|
* The type of this input (<input type=...>) as an integer.
|
|
|
|
* @see nsIFormControl.h (specifically NS_FORM_INPUT_*)
|
|
|
|
*/
|
2000-12-23 10:56:31 +00:00
|
|
|
PRInt8 mType;
|
2002-07-20 23:09:24 +00:00
|
|
|
/**
|
|
|
|
* A bitfield containing our booleans
|
|
|
|
* @see GET_BOOLBIT / SET_BOOLBIT macros and BF_* field identifiers
|
|
|
|
*/
|
2004-04-30 23:55:16 +00:00
|
|
|
PRInt16 mBitField;
|
2002-07-20 23:09:24 +00:00
|
|
|
/**
|
|
|
|
* The current value of the input if it has been changed from the deafault
|
|
|
|
*/
|
2001-11-02 07:40:01 +00:00
|
|
|
char* mValue;
|
1998-09-01 01:27:08 +00:00
|
|
|
};
|
|
|
|
|
2002-02-08 18:23:47 +00:00
|
|
|
//
|
1998-09-23 17:16:51 +00:00
|
|
|
// construction, destruction
|
2002-02-08 18:23:47 +00:00
|
|
|
//
|
1998-09-23 17:16:51 +00:00
|
|
|
|
2004-06-02 00:25:00 +00:00
|
|
|
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Input)
|
1998-09-01 01:27:08 +00:00
|
|
|
|
2004-05-18 20:58:12 +00:00
|
|
|
nsHTMLInputElement::nsHTMLInputElement(nsINodeInfo *aNodeInfo,
|
|
|
|
PRBool aFromParser)
|
|
|
|
: nsGenericHTMLFormElement(aNodeInfo),
|
|
|
|
mType(NS_FORM_INPUT_TEXT), // default value
|
|
|
|
mBitField(0),
|
|
|
|
mValue(nsnull)
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2002-03-31 10:14:01 +00:00
|
|
|
SET_BOOLBIT(mBitField, BF_PARSER_CREATING, aFromParser);
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::~nsHTMLInputElement()
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2001-11-02 07:40:01 +00:00
|
|
|
if (mValue) {
|
|
|
|
nsMemory::Free(mValue);
|
|
|
|
}
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsISupports
|
1998-09-01 01:27:08 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
NS_IMPL_ADDREF_INHERITED(nsHTMLInputElement, nsGenericElement)
|
|
|
|
NS_IMPL_RELEASE_INHERITED(nsHTMLInputElement, 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 nsHTMLInputElement
|
|
|
|
NS_HTML_CONTENT_INTERFACE_MAP_BEGIN(nsHTMLInputElement,
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement)
|
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(nsIDOMHTMLInputElement)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLInputElement)
|
2001-11-02 07:40:01 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsITextControlElement)
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIRadioControlElement)
|
2002-12-17 23:38:04 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIPhonetic)
|
2003-03-19 03:47:09 +00:00
|
|
|
NS_INTERFACE_MAP_ENTRY(imgIDecoderObserver)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIImageLoadingContent)
|
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(HTMLInputElement)
|
|
|
|
NS_HTML_CONTENT_INTERFACE_MAP_END
|
1998-09-01 01:27:08 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
|
1999-07-28 05:26:55 +00:00
|
|
|
// nsIDOMNode
|
1998-09-23 17:16:51 +00:00
|
|
|
|
1998-09-01 01:27:08 +00:00
|
|
|
nsresult
|
1998-10-20 17:07:23 +00:00
|
|
|
nsHTMLInputElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2000-12-23 10:56:31 +00:00
|
|
|
*aReturn = nsnull;
|
|
|
|
|
2004-05-18 20:58:12 +00:00
|
|
|
nsHTMLInputElement* it = new nsHTMLInputElement(mNodeInfo, PR_FALSE);
|
2000-12-23 10:56:31 +00:00
|
|
|
if (!it) {
|
1998-09-01 01:27:08 +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);
|
1998-09-01 01:27:08 +00:00
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
CopyInnerTo(it, aDeep);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-11-10 23:46:29 +00:00
|
|
|
switch (mType) {
|
|
|
|
case NS_FORM_INPUT_TEXT:
|
|
|
|
case NS_FORM_INPUT_PASSWORD:
|
|
|
|
case NS_FORM_INPUT_FILE:
|
|
|
|
if (GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
|
|
|
|
// We don't have our default value anymore. Set our value on
|
|
|
|
// the clone.
|
|
|
|
nsAutoString value;
|
|
|
|
GetValue(value);
|
|
|
|
// SetValueInternal handles setting the VALUE_CHANGED bit for us
|
|
|
|
it->SetValueInternal(value, nsnull);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
if (GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED)) {
|
|
|
|
// We no longer have our original checked state. Set our
|
|
|
|
// checked state on the clone.
|
|
|
|
PRBool checked;
|
|
|
|
GetChecked(&checked);
|
2004-01-21 04:28:57 +00:00
|
|
|
it->DoSetChecked(checked, PR_FALSE);
|
2003-11-10 23:46:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-05-18 20:58:12 +00:00
|
|
|
kungFuDeathGrip.swap(*aReturn);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
1999-07-28 05:26:55 +00:00
|
|
|
}
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
void
|
|
|
|
nsHTMLInputElement::BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString* aValue,
|
2002-03-07 20:53:40 +00:00
|
|
|
PRBool aNotify)
|
|
|
|
{
|
2004-02-24 23:55:18 +00:00
|
|
|
if (aNameSpaceID != kNameSpaceID_None) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
//
|
|
|
|
// When name or type changes, radio should be removed from radio group.
|
|
|
|
// (type changes are handled in the form itself currently)
|
|
|
|
// If the parser is not done creating the radio, we also should not do it.
|
|
|
|
//
|
|
|
|
if ((aName == nsHTMLAtoms::name || (aName == nsHTMLAtoms::type && !mForm)) &&
|
|
|
|
mType == NS_FORM_INPUT_RADIO &&
|
|
|
|
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
|
|
|
WillRemoveFromRadioGroup();
|
2003-07-24 17:10:14 +00:00
|
|
|
} else if (aNotify && aName == nsHTMLAtoms::src &&
|
2003-03-19 03:47:09 +00:00
|
|
|
aValue && mType == NS_FORM_INPUT_IMAGE) {
|
|
|
|
// Null value means the attr got unset; don't trigger on that
|
|
|
|
ImageURIChanged(*aValue);
|
2004-02-24 23:55:18 +00:00
|
|
|
} else if (aNotify && aName == nsHTMLAtoms::disabled) {
|
|
|
|
SET_BOOLBIT(mBitField, BF_DISABLED_CHANGED, PR_TRUE);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nsHTMLInputElement::AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString* aValue,
|
2002-03-07 20:53:40 +00:00
|
|
|
PRBool aNotify)
|
|
|
|
{
|
2004-02-24 23:55:18 +00:00
|
|
|
if (aNameSpaceID != kNameSpaceID_None) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2002-07-20 23:09:24 +00:00
|
|
|
// When name or type changes, radio should be added to radio group.
|
2002-03-07 20:53:40 +00:00
|
|
|
// (type changes are handled in the form itself currently)
|
2002-07-20 23:09:24 +00:00
|
|
|
// If the parser is not done creating the radio, we also should not do it.
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2002-07-20 23:09:24 +00:00
|
|
|
if ((aName == nsHTMLAtoms::name || (aName == nsHTMLAtoms::type && !mForm)) &&
|
|
|
|
mType == NS_FORM_INPUT_RADIO &&
|
|
|
|
(mForm || !(GET_BOOLBIT(mBitField, BF_PARSER_CREATING)))) {
|
2002-03-07 20:53:40 +00:00
|
|
|
AddedToRadioGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Some elements have to change their value when the value and checked
|
|
|
|
// attributes change (but they only do so when ValueChanged() and
|
|
|
|
// CheckedChanged() are false--i.e. the value has not been changed by the
|
|
|
|
// user or by JS)
|
|
|
|
//
|
2002-03-12 07:05:05 +00:00
|
|
|
// We only really need to call reset for the value so that the text control
|
|
|
|
// knows the new value. No other reason.
|
|
|
|
//
|
2002-03-07 20:53:40 +00:00
|
|
|
if (aName == nsHTMLAtoms::value &&
|
|
|
|
!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) &&
|
|
|
|
(mType == NS_FORM_INPUT_TEXT ||
|
|
|
|
mType == NS_FORM_INPUT_PASSWORD ||
|
2002-03-12 07:05:05 +00:00
|
|
|
mType == NS_FORM_INPUT_FILE)) {
|
2002-03-07 20:53:40 +00:00
|
|
|
Reset();
|
|
|
|
}
|
2002-03-12 07:05:05 +00:00
|
|
|
//
|
|
|
|
// Checked must be set no matter what type of control it is, since
|
|
|
|
// GetChecked() must reflect the new value
|
|
|
|
//
|
2002-03-07 20:53:40 +00:00
|
|
|
if (aName == nsHTMLAtoms::checked &&
|
2002-03-12 07:05:05 +00:00
|
|
|
!GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED)) {
|
2002-03-31 10:14:01 +00:00
|
|
|
// Delay setting checked if the parser is creating this element (wait until
|
|
|
|
// everything is set)
|
|
|
|
if (GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) {
|
|
|
|
SET_BOOLBIT(mBitField, BF_SHOULD_INIT_CHECKED, PR_TRUE);
|
|
|
|
} else {
|
|
|
|
PRBool defaultChecked;
|
|
|
|
GetDefaultChecked(&defaultChecked);
|
2004-01-21 04:28:57 +00:00
|
|
|
DoSetChecked(defaultChecked);
|
2002-03-31 10:14:01 +00:00
|
|
|
SetCheckedChanged(PR_FALSE);
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
2002-12-17 13:29:39 +00:00
|
|
|
|
|
|
|
if (aName == nsHTMLAtoms::type) {
|
|
|
|
// If we are changing type from File/Text/Passwd to other input types
|
|
|
|
// we need save the mValue into value attribute
|
|
|
|
if (mValue &&
|
|
|
|
mType != NS_FORM_INPUT_TEXT &&
|
|
|
|
mType != NS_FORM_INPUT_PASSWORD &&
|
|
|
|
mType != NS_FORM_INPUT_FILE) {
|
|
|
|
SetAttr(kNameSpaceID_None, nsHTMLAtoms::value,
|
|
|
|
NS_ConvertUTF8toUCS2(mValue), PR_FALSE);
|
|
|
|
if (mValue) {
|
|
|
|
nsMemory::Free(mValue);
|
|
|
|
mValue = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-07-24 17:10:14 +00:00
|
|
|
if (aNotify && mType == NS_FORM_INPUT_IMAGE && !mCurrentRequest) {
|
2003-03-19 03:47:09 +00:00
|
|
|
// We just got switched to be an image input; we should see
|
|
|
|
// whether we have an image to load;
|
|
|
|
nsAutoString src;
|
2003-07-24 17:10:14 +00:00
|
|
|
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, src);
|
|
|
|
if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
ImageURIChanged(src);
|
|
|
|
}
|
2003-03-19 03:47:09 +00:00
|
|
|
}
|
2002-12-16 23:49:16 +00:00
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
2002-08-06 23:50:08 +00:00
|
|
|
// nsIDOMHTMLInputElement
|
|
|
|
|
1998-09-01 01:27:08 +00:00
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2004-02-10 19:36:43 +00:00
|
|
|
return nsGenericHTMLFormElement::GetForm(aForm);
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
2004-02-24 23:55:18 +00:00
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, DefaultValue, value)
|
|
|
|
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, DefaultChecked, checked)
|
1998-11-03 01:08:02 +00:00
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Accept, accept)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, AccessKey, accesskey)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Align, align)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Alt, alt)
|
|
|
|
//NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Checked, checked)
|
2004-02-24 23:55:18 +00:00
|
|
|
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Disabled, disabled)
|
1998-11-03 01:08:02 +00:00
|
|
|
NS_IMPL_INT_ATTR(nsHTMLInputElement, MaxLength, maxlength)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Name, name)
|
|
|
|
NS_IMPL_BOOL_ATTR(nsHTMLInputElement, ReadOnly, readonly)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, Src, src)
|
|
|
|
NS_IMPL_INT_ATTR(nsHTMLInputElement, TabIndex, tabindex)
|
|
|
|
NS_IMPL_STRING_ATTR(nsHTMLInputElement, UseMap, usemap)
|
|
|
|
//NS_IMPL_STRING_ATTR(nsHTMLInputElement, Value, value)
|
2004-02-24 23:55:18 +00:00
|
|
|
//NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Size, size, 0)
|
2004-06-26 16:49:33 +00:00
|
|
|
//NS_IMPL_STRING_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Type, type, "text")
|
2003-11-10 05:52:29 +00:00
|
|
|
|
2002-12-17 13:29:39 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetSize(PRUint32* aValue)
|
|
|
|
{
|
2002-12-17 19:35:03 +00:00
|
|
|
*aValue = 0;
|
|
|
|
|
2002-12-17 13:29:39 +00:00
|
|
|
nsHTMLValue value;
|
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE ==
|
2004-02-11 00:09:59 +00:00
|
|
|
GetHTMLAttribute(nsHTMLAtoms::size, value) &&
|
|
|
|
value.GetUnit() == eHTMLUnit_Integer) {
|
|
|
|
*aValue = value.GetIntValue();
|
2002-12-17 13:29:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetSize(PRUint32 aValue)
|
|
|
|
{
|
2004-02-24 23:55:18 +00:00
|
|
|
nsAutoString val;
|
|
|
|
val.AppendInt(aValue);
|
2000-08-25 01:57:28 +00:00
|
|
|
|
2004-02-24 23:55:18 +00:00
|
|
|
return SetAttr(kNameSpaceID_None, nsHTMLAtoms::size, val, PR_TRUE);
|
2000-08-25 01:57:28 +00:00
|
|
|
}
|
|
|
|
|
1998-10-30 20:41:01 +00:00
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsHTMLInputElement::GetValue(nsAString& aValue)
|
1998-10-30 20:41:01 +00:00
|
|
|
{
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD ||
|
|
|
|
mType == NS_FORM_INPUT_FILE) {
|
2001-11-06 09:10:07 +00:00
|
|
|
// No need to flush here, if there's no frame created for this
|
|
|
|
// input yet, there won't be a value in it (that we don't already
|
|
|
|
// have) even if we force it to be created
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2001-11-19 10:35:52 +00:00
|
|
|
PRBool frameOwnsValue = PR_FALSE;
|
2001-11-02 07:40:01 +00:00
|
|
|
if (formControlFrame) {
|
2002-07-26 20:57:24 +00:00
|
|
|
nsITextControlFrame* textControlFrame = nsnull;
|
2001-11-16 02:38:10 +00:00
|
|
|
CallQueryInterface(formControlFrame, &textControlFrame);
|
|
|
|
|
2001-11-19 10:35:52 +00:00
|
|
|
if (textControlFrame) {
|
|
|
|
textControlFrame->OwnsValue(&frameOwnsValue);
|
|
|
|
} else {
|
|
|
|
// We assume if it's not a text control frame that it owns the value
|
|
|
|
frameOwnsValue = PR_TRUE;
|
|
|
|
}
|
2001-11-16 02:38:10 +00:00
|
|
|
}
|
2001-11-19 10:35:52 +00:00
|
|
|
|
2001-11-16 02:38:10 +00:00
|
|
|
if (frameOwnsValue) {
|
2001-11-02 07:40:01 +00:00
|
|
|
formControlFrame->GetProperty(nsHTMLAtoms::value, aValue);
|
|
|
|
} else {
|
2002-02-08 18:23:47 +00:00
|
|
|
if (!GET_BOOLBIT(mBitField, BF_VALUE_CHANGED) || !mValue) {
|
2001-11-16 02:38:10 +00:00
|
|
|
GetDefaultValue(aValue);
|
|
|
|
} else {
|
2003-06-21 00:26:28 +00:00
|
|
|
CopyUTF8toUTF16(mValue, aValue);
|
2001-11-16 02:38:10 +00:00
|
|
|
}
|
2000-01-14 09:28:54 +00:00
|
|
|
}
|
2001-11-19 10:35:52 +00:00
|
|
|
|
2001-01-30 04:22:24 +00:00
|
|
|
return NS_OK;
|
2001-02-09 23:45:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Treat value == defaultValue for other input elements
|
2002-05-20 22:47:02 +00:00
|
|
|
nsresult rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::value, aValue);
|
2001-02-09 23:45:41 +00:00
|
|
|
|
2001-11-09 06:14:52 +00:00
|
|
|
if (rv == NS_CONTENT_ATTR_NOT_THERE &&
|
2002-12-18 23:38:09 +00:00
|
|
|
(mType == NS_FORM_INPUT_RADIO || mType == NS_FORM_INPUT_CHECKBOX)) {
|
2001-11-09 06:14:52 +00:00
|
|
|
// The default value of a radio or checkbox input is "on".
|
2004-06-17 00:13:25 +00:00
|
|
|
aValue.AssignLiteral("on");
|
2001-01-30 04:22:24 +00:00
|
|
|
|
2000-01-14 09:28:54 +00:00
|
|
|
return NS_OK;
|
1999-01-28 18:58:11 +00:00
|
|
|
}
|
2001-01-30 04:22:24 +00:00
|
|
|
|
2001-02-09 23:45:41 +00:00
|
|
|
return rv;
|
1998-10-30 20:41:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-03-23 23:04:39 +00:00
|
|
|
nsHTMLInputElement::SetValue(const nsAString& aValue)
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
2002-12-16 23:49:16 +00:00
|
|
|
//check secuity
|
|
|
|
if (mType == NS_FORM_INPUT_FILE) {
|
2003-10-30 03:01:25 +00:00
|
|
|
nsIScriptSecurityManager *securityManager =
|
|
|
|
nsContentUtils::GetSecurityManager();
|
2002-12-16 23:49:16 +00:00
|
|
|
|
|
|
|
PRBool enabled;
|
2003-10-30 03:01:25 +00:00
|
|
|
nsresult rv =
|
|
|
|
securityManager->IsCapabilityEnabled("UniversalFileRead", &enabled);
|
2002-12-16 23:49:16 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
if (!enabled) {
|
|
|
|
// setting the value of a "FILE" input widget requires the
|
|
|
|
// UniversalFileRead privilege
|
|
|
|
return NS_ERROR_DOM_SECURITY_ERR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SetValueInternal(aValue, nsnull);
|
|
|
|
return NS_OK;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
2001-11-19 10:35:52 +00:00
|
|
|
NS_IMETHODIMP
|
2002-12-16 23:49:16 +00:00
|
|
|
nsHTMLInputElement::TakeTextFrameValue(const nsAString& aValue)
|
2001-11-19 10:35:52 +00:00
|
|
|
{
|
2002-12-16 23:49:16 +00:00
|
|
|
if (mValue) {
|
|
|
|
nsMemory::Free(mValue);
|
|
|
|
}
|
|
|
|
mValue = ToNewUTF8String(aValue);
|
|
|
|
SetValueChanged(PR_TRUE);
|
|
|
|
return NS_OK;
|
2001-11-19 10:35:52 +00:00
|
|
|
}
|
|
|
|
|
2002-12-16 23:49:16 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLInputElement::SetValueInternal(const nsAString& aValue,
|
|
|
|
nsITextControlFrame* aFrame)
|
1998-10-30 20:41:01 +00:00
|
|
|
{
|
2002-12-16 23:49:16 +00:00
|
|
|
if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD ||
|
|
|
|
mType == NS_FORM_INPUT_FILE) {
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2002-07-26 20:57:24 +00:00
|
|
|
nsITextControlFrame* textControlFrame = aFrame;
|
2001-12-11 05:39:36 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = textControlFrame;
|
|
|
|
if (!textControlFrame) {
|
|
|
|
// No need to flush here, if there's no frame at this point we
|
|
|
|
// don't need to force creation of one just to tell it about this
|
|
|
|
// new value.
|
2001-12-12 07:31:15 +00:00
|
|
|
formControlFrame = GetFormControlFrame(PR_FALSE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2001-12-11 05:39:36 +00:00
|
|
|
if (formControlFrame) {
|
|
|
|
CallQueryInterface(formControlFrame, &textControlFrame);
|
|
|
|
}
|
2001-11-16 02:38:10 +00:00
|
|
|
}
|
|
|
|
|
2002-03-31 10:14:01 +00:00
|
|
|
// File frames always own the value (if the frame is there).
|
|
|
|
// Text frames have a bit that says whether they own the value.
|
2001-11-16 02:38:10 +00:00
|
|
|
PRBool frameOwnsValue = PR_FALSE;
|
2002-12-16 23:49:16 +00:00
|
|
|
if (mType == NS_FORM_INPUT_FILE && formControlFrame) {
|
2002-03-31 10:14:01 +00:00
|
|
|
frameOwnsValue = PR_TRUE;
|
|
|
|
}
|
2001-11-16 02:38:10 +00:00
|
|
|
if (textControlFrame) {
|
|
|
|
textControlFrame->OwnsValue(&frameOwnsValue);
|
|
|
|
}
|
2002-06-12 06:35:11 +00:00
|
|
|
// If the frame owns the value, set the value in the frame
|
2001-11-16 02:38:10 +00:00
|
|
|
if (frameOwnsValue) {
|
2001-11-02 07:40:01 +00:00
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
|
|
|
formControlFrame->SetProperty(presContext, nsHTMLAtoms::value, aValue);
|
2002-06-12 06:35:11 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-11-16 02:38:10 +00:00
|
|
|
|
2002-06-12 06:35:11 +00:00
|
|
|
// If the frame does not own the value, set mValue
|
|
|
|
if (mValue) {
|
|
|
|
nsMemory::Free(mValue);
|
2000-01-14 09:28:54 +00:00
|
|
|
}
|
2001-11-16 02:38:10 +00:00
|
|
|
|
2002-06-12 06:35:11 +00:00
|
|
|
mValue = ToNewUTF8String(aValue);
|
|
|
|
|
|
|
|
SetValueChanged(PR_TRUE);
|
|
|
|
return mValue ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the value of a hidden input was changed, we mark it changed so that we
|
|
|
|
// will know we need to save / restore the value. Yes, we are overloading
|
|
|
|
// the meaning of ValueChanged just a teensy bit to save a measly byte of
|
|
|
|
// storage space in nsHTMLInputElement. Yes, you are free to make a new flag,
|
|
|
|
// NEED_TO_SAVE_VALUE, at such time as mBitField becomes a 16-bit value.
|
2002-12-16 23:49:16 +00:00
|
|
|
if (mType == NS_FORM_INPUT_HIDDEN) {
|
2002-06-12 06:35:11 +00:00
|
|
|
SetValueChanged(PR_TRUE);
|
1999-03-03 02:54:25 +00:00
|
|
|
}
|
2000-01-14 09:28:54 +00:00
|
|
|
|
1999-03-03 02:54:25 +00:00
|
|
|
// Treat value == defaultValue for other input elements.
|
2004-02-10 19:36:43 +00:00
|
|
|
return nsGenericHTMLFormElement::SetAttr(kNameSpaceID_None,
|
|
|
|
nsHTMLAtoms::value, aValue,
|
|
|
|
PR_TRUE);
|
1998-10-30 20:41:01 +00:00
|
|
|
}
|
|
|
|
|
2001-11-05 06:50:21 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetValueChanged(PRBool aValueChanged)
|
|
|
|
{
|
2002-02-08 18:23:47 +00:00
|
|
|
SET_BOOLBIT(mBitField, BF_VALUE_CHANGED, aValueChanged);
|
2001-11-05 06:50:21 +00:00
|
|
|
if (!aValueChanged) {
|
|
|
|
if (mValue) {
|
|
|
|
nsMemory::Free(mValue);
|
|
|
|
mValue = nsnull;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1998-10-30 20:41:01 +00:00
|
|
|
NS_IMETHODIMP
|
2002-01-24 19:04:55 +00:00
|
|
|
nsHTMLInputElement::GetChecked(PRBool* aChecked)
|
1998-10-30 20:41:01 +00:00
|
|
|
{
|
2002-03-07 20:53:40 +00:00
|
|
|
*aChecked = GET_BOOLBIT(mBitField, BF_CHECKED);
|
2002-01-24 19:04:55 +00:00
|
|
|
return NS_OK;
|
1998-10-30 20:41:01 +00:00
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetCheckedChanged(PRBool aCheckedChanged)
|
|
|
|
{
|
|
|
|
if (mType == NS_FORM_INPUT_RADIO) {
|
|
|
|
if (GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED) != aCheckedChanged) {
|
|
|
|
nsCOMPtr<nsIRadioVisitor> visitor;
|
|
|
|
NS_GetRadioSetCheckedChangedVisitor(aCheckedChanged,
|
|
|
|
getter_AddRefs(visitor));
|
|
|
|
VisitGroup(visitor);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
SetCheckedChangedInternal(aCheckedChanged);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetCheckedChangedInternal(PRBool aCheckedChanged)
|
|
|
|
{
|
|
|
|
SET_BOOLBIT(mBitField, BF_CHECKED_CHANGED, aCheckedChanged);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetCheckedChanged(PRBool* aCheckedChanged)
|
|
|
|
{
|
|
|
|
*aCheckedChanged = GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetChecked(PRBool aChecked)
|
2004-01-21 04:28:57 +00:00
|
|
|
{
|
|
|
|
return DoSetChecked(aChecked);
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLInputElement::DoSetChecked(PRBool aChecked, PRBool aNotify)
|
2002-03-07 20:53:40 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
//
|
|
|
|
// If the user or JS attempts to set checked, whether it actually changes the
|
|
|
|
// value or not, we say the value was changed so that defaultValue don't
|
|
|
|
// affect it no more.
|
|
|
|
//
|
|
|
|
SetCheckedChanged(PR_TRUE);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Don't do anything if we're not changing whether it's checked (it would
|
|
|
|
// screw up state actually, especially when you are setting radio button to
|
|
|
|
// false)
|
|
|
|
//
|
|
|
|
PRBool checked = PR_FALSE;
|
|
|
|
GetChecked(&checked);
|
|
|
|
if (checked == aChecked) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Set checked
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_RADIO) {
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
|
|
|
// For radio button, we need to do some extra fun stuff
|
|
|
|
//
|
|
|
|
if (aChecked) {
|
2004-01-21 04:28:57 +00:00
|
|
|
rv = RadioSetChecked(aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
} else {
|
2004-01-21 04:28:57 +00:00
|
|
|
rv = SetCheckedInternal(PR_FALSE, aNotify);
|
2002-07-20 23:09:24 +00:00
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
if (container) {
|
2002-03-07 20:53:40 +00:00
|
|
|
nsAutoString name;
|
2002-08-06 04:32:57 +00:00
|
|
|
if (GetNameIfExists(name)) {
|
|
|
|
container->SetCurrentRadioButton(name, nsnull);
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2004-01-21 04:28:57 +00:00
|
|
|
rv = SetCheckedInternal(aChecked, aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2004-01-21 04:28:57 +00:00
|
|
|
nsHTMLInputElement::RadioSetChecked(PRBool aNotify)
|
1998-10-30 20:41:01 +00:00
|
|
|
{
|
2002-03-07 20:53:40 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Find the selected radio button so we can deselect it
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> currentlySelected;
|
2002-07-20 23:09:24 +00:00
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
// This is ONLY INITIALIZED IF container EXISTS
|
2002-03-07 20:53:40 +00:00
|
|
|
nsAutoString name;
|
2002-08-06 04:32:57 +00:00
|
|
|
PRBool nameExists = PR_FALSE;
|
2002-07-20 23:09:24 +00:00
|
|
|
if (container) {
|
2002-08-06 04:32:57 +00:00
|
|
|
nameExists = GetNameIfExists(name);
|
|
|
|
if (nameExists) {
|
|
|
|
container->GetCurrentRadioButton(name, getter_AddRefs(currentlySelected));
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Deselect the currently selected radio button
|
|
|
|
//
|
|
|
|
if (currentlySelected) {
|
2004-01-21 04:28:57 +00:00
|
|
|
// Pass PR_TRUE for the aNotify parameter since the currently selected
|
|
|
|
// button is already in the document.
|
2002-03-07 20:53:40 +00:00
|
|
|
rv = NS_STATIC_CAST(nsHTMLInputElement*,
|
|
|
|
NS_STATIC_CAST(nsIDOMHTMLInputElement*, currentlySelected)
|
2004-01-21 04:28:57 +00:00
|
|
|
)->SetCheckedInternal(PR_FALSE, PR_TRUE);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
2000-06-22 02:46:53 +00:00
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
|
|
|
// Actually select this one
|
|
|
|
//
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2004-01-21 04:28:57 +00:00
|
|
|
rv = SetCheckedInternal(PR_TRUE, aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2002-07-20 23:09:24 +00:00
|
|
|
// Let the group know that we are now the One True Radio Button
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2002-07-20 23:09:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-08-06 04:32:57 +00:00
|
|
|
if (container && nameExists) {
|
2002-07-20 23:09:24 +00:00
|
|
|
rv = container->SetCurrentRadioButton(name, this);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
already_AddRefed<nsIRadioGroupContainer>
|
|
|
|
nsHTMLInputElement::GetRadioGroupContainer()
|
|
|
|
{
|
|
|
|
nsIRadioGroupContainer* retval = nsnull;
|
|
|
|
if (mForm) {
|
|
|
|
CallQueryInterface(mForm, &retval);
|
2003-11-07 17:07:03 +00:00
|
|
|
} else if (mDocument && GetParent()) {
|
2002-07-20 23:09:24 +00:00
|
|
|
CallQueryInterface(mDocument, &retval);
|
|
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2004-01-05 23:39:50 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLInputElement::MaybeSubmitForm(nsIPresContext* aPresContext)
|
|
|
|
{
|
|
|
|
if (!mForm) {
|
|
|
|
// Nothing to do here.
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the first submit control in elements[]
|
|
|
|
// and also check how many text controls we have in the form
|
|
|
|
nsCOMPtr<nsIContent> submitControl;
|
|
|
|
PRInt32 numTextControlsFound = 0;
|
|
|
|
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> formControls;
|
|
|
|
mForm->GetControlEnumerator(getter_AddRefs(formControls));
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupports> currentControlSupports;
|
|
|
|
nsCOMPtr<nsIFormControl> currentControl;
|
|
|
|
PRBool hasMoreElements;
|
|
|
|
nsresult rv;
|
|
|
|
while (NS_SUCCEEDED(rv = formControls->HasMoreElements(&hasMoreElements)) &&
|
|
|
|
hasMoreElements) {
|
|
|
|
rv = formControls->GetNext(getter_AddRefs(currentControlSupports));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
currentControl = do_QueryInterface(currentControlSupports);
|
|
|
|
if (currentControl) {
|
|
|
|
PRInt32 type = currentControl->GetType();
|
|
|
|
if (!submitControl &&
|
|
|
|
(type == NS_FORM_INPUT_SUBMIT ||
|
|
|
|
type == NS_FORM_BUTTON_SUBMIT ||
|
|
|
|
type == NS_FORM_INPUT_IMAGE)) {
|
|
|
|
submitControl = do_QueryInterface(currentControl);
|
|
|
|
// We know as soon as we find a submit control that it no
|
|
|
|
// longer matters how many text controls there are--we are
|
|
|
|
// going to fire the onClick handler.
|
|
|
|
break;
|
|
|
|
} else if (type == NS_FORM_INPUT_TEXT ||
|
|
|
|
type == NS_FORM_INPUT_PASSWORD) {
|
|
|
|
numTextControlsFound++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsIPresShell* shell = aPresContext->GetPresShell();
|
|
|
|
if (shell) {
|
|
|
|
if (submitControl) {
|
|
|
|
// Fire the button's onclick handler and let the button handle
|
|
|
|
// submitting the form.
|
2004-01-12 08:25:18 +00:00
|
|
|
nsGUIEvent event(NS_MOUSE_LEFT_CLICK);
|
2004-01-05 23:39:50 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
shell->HandleDOMEventWithTarget(submitControl, &event, &status);
|
|
|
|
} else if (numTextControlsFound == 1) {
|
|
|
|
// If there's only one text control, just submit the form
|
|
|
|
nsCOMPtr<nsIContent> form = do_QueryInterface(mForm);
|
2004-01-12 08:25:18 +00:00
|
|
|
nsFormEvent event(NS_FORM_SUBMIT);
|
2004-01-05 23:39:50 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
shell->HandleDOMEventWithTarget(form, &event, &status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
nsresult
|
2004-01-21 04:28:57 +00:00
|
|
|
nsHTMLInputElement::SetCheckedInternal(PRBool aChecked, PRBool aNotify)
|
2002-03-07 20:53:40 +00:00
|
|
|
{
|
2002-01-24 19:04:55 +00:00
|
|
|
//
|
|
|
|
// Set the value
|
|
|
|
//
|
2002-03-07 20:53:40 +00:00
|
|
|
SET_BOOLBIT(mBitField, BF_CHECKED, aChecked);
|
2000-06-22 02:46:53 +00:00
|
|
|
|
2002-01-24 19:04:55 +00:00
|
|
|
//
|
|
|
|
// Notify the frame
|
|
|
|
//
|
2002-05-16 18:26:05 +00:00
|
|
|
nsIFrame* frame = GetPrimaryFrame(PR_FALSE);
|
2004-01-21 04:28:57 +00:00
|
|
|
if (frame) {
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
2002-01-24 19:04:55 +00:00
|
|
|
|
2004-01-21 04:28:57 +00:00
|
|
|
if (mType == NS_FORM_INPUT_CHECKBOX) {
|
|
|
|
nsICheckboxControlFrame* checkboxFrame = nsnull;
|
|
|
|
CallQueryInterface(frame, &checkboxFrame);
|
|
|
|
if (checkboxFrame) {
|
|
|
|
checkboxFrame->OnChecked(presContext, aChecked);
|
|
|
|
}
|
|
|
|
} else if (mType == NS_FORM_INPUT_RADIO) {
|
|
|
|
nsIRadioControlFrame* radioFrame = nsnull;
|
|
|
|
CallQueryInterface(frame, &radioFrame);
|
|
|
|
if (radioFrame) {
|
|
|
|
radioFrame->OnChecked(presContext, aChecked);
|
|
|
|
}
|
2000-01-14 09:57:31 +00:00
|
|
|
}
|
|
|
|
}
|
2002-03-13 10:12:33 +00:00
|
|
|
|
|
|
|
// Notify the document that the CSS :checked pseudoclass for this element
|
|
|
|
// has changed state.
|
2004-01-21 04:28:57 +00:00
|
|
|
if (mDocument && aNotify) {
|
|
|
|
mozAutoDocUpdate(mDocument, UPDATE_CONTENT_STATE, aNotify);
|
2002-04-11 03:49:30 +00:00
|
|
|
mDocument->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_CHECKED);
|
2002-04-03 05:09:27 +00:00
|
|
|
}
|
2000-01-14 09:57:31 +00:00
|
|
|
|
2002-01-24 19:04:55 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2002-04-03 05:09:27 +00:00
|
|
|
|
2002-01-24 19:04:55 +00:00
|
|
|
void
|
|
|
|
nsHTMLInputElement::FireOnChange()
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Since the value is changing, send out an onchange event (bug 23571)
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
2000-08-29 01:50:31 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2004-01-12 08:25:18 +00:00
|
|
|
nsEvent event(NS_FORM_CHANGE);
|
2000-08-29 01:50:31 +00:00
|
|
|
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1998-10-30 20:41:01 +00:00
|
|
|
}
|
|
|
|
|
1998-09-01 01:27:08 +00:00
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::Blur()
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2004-01-09 23:54:21 +00:00
|
|
|
SetElementFocus(PR_FALSE);
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::Focus()
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2004-01-09 23:54:21 +00:00
|
|
|
SetElementFocus(PR_TRUE);
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
void
|
1999-03-02 19:19:24 +00:00
|
|
|
nsHTMLInputElement::SetFocus(nsIPresContext* aPresContext)
|
|
|
|
{
|
2004-01-09 23:54:21 +00:00
|
|
|
if (!aPresContext)
|
|
|
|
return;
|
2001-04-19 23:28:57 +00:00
|
|
|
|
|
|
|
// We can't be focus'd if we don't have a document
|
2004-01-09 23:54:21 +00:00
|
|
|
if (!mDocument)
|
|
|
|
return;
|
2001-04-19 23:28:57 +00:00
|
|
|
|
2000-01-29 04:05:03 +00:00
|
|
|
// first see if we are disabled or not. If disabled then do nothing.
|
|
|
|
nsAutoString disabled;
|
2002-05-20 22:47:02 +00:00
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttr(kNameSpaceID_None,
|
2001-12-12 07:31:15 +00:00
|
|
|
nsHTMLAtoms::disabled, disabled)) {
|
2004-01-09 23:54:21 +00:00
|
|
|
return;
|
2000-01-29 04:05:03 +00:00
|
|
|
}
|
2000-04-04 23:55:31 +00:00
|
|
|
|
2001-04-18 01:41:20 +00:00
|
|
|
// If the window is not active, do not allow the focus to bring the
|
|
|
|
// window to the front. We update the focus controller, but do
|
|
|
|
// nothing else.
|
2003-10-22 06:09:48 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mDocument->GetScriptGlobalObject()));
|
2004-05-03 21:48:36 +00:00
|
|
|
nsIFocusController *focusController = win->GetRootFocusController();
|
2001-04-18 01:41:20 +00:00
|
|
|
PRBool isActive = PR_FALSE;
|
|
|
|
focusController->GetActive(&isActive);
|
|
|
|
if (!isActive) {
|
2004-05-03 21:48:36 +00:00
|
|
|
focusController->SetFocusedWindow(win);
|
2001-04-18 01:41:20 +00:00
|
|
|
focusController->SetFocusedElement(this);
|
2004-01-09 23:54:21 +00:00
|
|
|
|
|
|
|
return;
|
2001-04-18 01:41:20 +00:00
|
|
|
}
|
|
|
|
|
2004-02-27 17:17:37 +00:00
|
|
|
aPresContext->EventStateManager()->SetContentState(this,
|
|
|
|
NS_EVENT_STATE_FOCUS);
|
2000-04-04 23:55:31 +00:00
|
|
|
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
2000-02-23 08:10:36 +00:00
|
|
|
formControlFrame->SetFocus(PR_TRUE, PR_TRUE);
|
1999-08-21 00:19:34 +00:00
|
|
|
formControlFrame->ScrollIntoView(aPresContext);
|
2000-05-30 02:45:55 +00:00
|
|
|
// Could call SelectAll(aPresContext) here to automatically
|
|
|
|
// select text when we receive focus - only for text and password!
|
1999-08-21 00:19:34 +00:00
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
void
|
1999-03-02 19:19:24 +00:00
|
|
|
nsHTMLInputElement::RemoveFocus(nsIPresContext* aPresContext)
|
|
|
|
{
|
2004-01-09 23:54:21 +00:00
|
|
|
if (!aPresContext)
|
|
|
|
return;
|
|
|
|
|
2000-09-08 01:46:00 +00:00
|
|
|
// If we are disabled, we probably shouldn't have focus in the
|
|
|
|
// first place, so allow it to be removed.
|
|
|
|
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2001-04-17 08:35:49 +00:00
|
|
|
if (formControlFrame) {
|
2000-09-08 01:46:00 +00:00
|
|
|
formControlFrame->SetFocus(PR_FALSE, PR_FALSE);
|
|
|
|
}
|
|
|
|
|
2004-02-27 17:17:37 +00:00
|
|
|
if (mDocument) {
|
|
|
|
aPresContext->EventStateManager()->SetContentState(nsnull,
|
|
|
|
NS_EVENT_STATE_FOCUS);
|
2000-09-08 01:46:00 +00:00
|
|
|
}
|
1999-03-02 19:19:24 +00:00
|
|
|
}
|
|
|
|
|
1998-09-01 01:27:08 +00:00
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::Select()
|
2000-05-30 02:45:55 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
2002-03-16 03:28:23 +00:00
|
|
|
if (!mDocument)
|
|
|
|
return NS_OK;
|
2000-05-30 02:45:55 +00:00
|
|
|
|
|
|
|
// first see if we are disabled or not. If disabled then do nothing.
|
|
|
|
nsAutoString disabled;
|
2002-05-20 22:47:02 +00:00
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttr(kNameSpaceID_None,
|
2001-12-12 07:31:15 +00:00
|
|
|
nsHTMLAtoms::disabled, disabled)) {
|
2000-05-30 02:45:55 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_PASSWORD || mType == NS_FORM_INPUT_TEXT) {
|
2000-12-23 10:56:31 +00:00
|
|
|
// XXX Bug? We have to give the input focus before contents can be
|
|
|
|
// selected
|
2000-09-09 01:22:01 +00:00
|
|
|
|
2000-05-30 02:45:55 +00:00
|
|
|
nsCOMPtr<nsIPresContext> presContext;
|
2000-12-23 10:56:31 +00:00
|
|
|
GetPresContext(this, getter_AddRefs(presContext));
|
2001-08-18 23:55:01 +00:00
|
|
|
|
|
|
|
// If the window is not active, do not allow the select to bring the
|
|
|
|
// window to the front. We update the focus controller, but do
|
|
|
|
// nothing else.
|
2003-10-22 06:09:48 +00:00
|
|
|
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mDocument->GetScriptGlobalObject()));
|
2004-05-03 21:48:36 +00:00
|
|
|
nsIFocusController *focusController = win->GetRootFocusController();
|
2001-08-18 23:55:01 +00:00
|
|
|
PRBool isActive = PR_FALSE;
|
|
|
|
focusController->GetActive(&isActive);
|
|
|
|
if (!isActive) {
|
2004-05-03 21:48:36 +00:00
|
|
|
focusController->SetFocusedWindow(win);
|
2001-08-18 23:55:01 +00:00
|
|
|
focusController->SetFocusedElement(this);
|
|
|
|
SelectAll(presContext);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just like SetFocus() but without the ScrollIntoView()!
|
2000-09-08 01:46:00 +00:00
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2002-02-20 03:18:14 +00:00
|
|
|
|
|
|
|
//If already handling select event, don't dispatch a second.
|
|
|
|
if (!GET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT)) {
|
2004-01-12 08:25:18 +00:00
|
|
|
nsEvent event(NS_FORM_SELECTED);
|
2002-02-20 03:18:14 +00:00
|
|
|
|
|
|
|
SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_TRUE);
|
|
|
|
rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
|
|
|
&status);
|
|
|
|
SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_FALSE);
|
|
|
|
}
|
2000-05-30 02:45:55 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
// If the DOM event was not canceled (e.g. by a JS event handler
|
|
|
|
// returning false)
|
2000-09-09 01:22:01 +00:00
|
|
|
if (status == nsEventStatus_eIgnore) {
|
2003-01-14 05:54:38 +00:00
|
|
|
if (presContext) {
|
2004-02-27 17:17:37 +00:00
|
|
|
nsIEventStateManager *esm = presContext->EventStateManager();
|
|
|
|
// XXX Fix for bug 135345 - ESM currently does not check to see if we
|
|
|
|
// have focus before attempting to set focus again and may cause
|
|
|
|
// infinite recursion. For now check if we have focus and do not set
|
|
|
|
// focus again if already focused.
|
|
|
|
PRInt32 currentState;
|
|
|
|
esm->GetContentState(this, currentState);
|
|
|
|
if (!(currentState & NS_EVENT_STATE_FOCUS)) {
|
|
|
|
esm->SetContentState(this, NS_EVENT_STATE_FOCUS);
|
2002-04-15 23:29:15 +00:00
|
|
|
}
|
2000-09-09 01:22:01 +00:00
|
|
|
}
|
|
|
|
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2001-11-02 07:40:01 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
2000-09-09 01:22:01 +00:00
|
|
|
formControlFrame->SetFocus(PR_TRUE, PR_TRUE);
|
|
|
|
|
|
|
|
// Now Select all the text!
|
|
|
|
SelectAll(presContext);
|
|
|
|
}
|
|
|
|
}
|
2000-05-30 02:45:55 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2000-05-30 02:45:55 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
void
|
2000-05-30 02:45:55 +00:00
|
|
|
nsHTMLInputElement::SelectAll(nsIPresContext* aPresContext)
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
|
|
|
formControlFrame->SetProperty(aPresContext, nsHTMLAtoms::select,
|
2004-05-22 20:02:43 +00:00
|
|
|
EmptyString());
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::Click()
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2000-05-30 02:45:55 +00:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2002-02-08 18:23:47 +00:00
|
|
|
if (GET_BOOLBIT(mBitField, BF_HANDLING_CLICK)) // Fixes crash as in bug 41599
|
|
|
|
return rv; // --heikki@netscape.com
|
2000-08-01 21:40:38 +00:00
|
|
|
|
2000-05-30 02:45:55 +00:00
|
|
|
// first see if we are disabled or not. If disabled then do nothing.
|
|
|
|
nsAutoString disabled;
|
2002-05-20 22:47:02 +00:00
|
|
|
if (NS_CONTENT_ATTR_HAS_VALUE == GetAttr(kNameSpaceID_None,
|
2001-12-12 07:31:15 +00:00
|
|
|
nsHTMLAtoms::disabled, disabled)) {
|
2000-05-30 02:45:55 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
// see what type of input we are. Only click button, checkbox, radio,
|
|
|
|
// reset, submit, & image
|
2003-09-27 04:18:26 +00:00
|
|
|
if (mDocument &&
|
|
|
|
(mType == NS_FORM_INPUT_BUTTON ||
|
|
|
|
mType == NS_FORM_INPUT_CHECKBOX ||
|
|
|
|
mType == NS_FORM_INPUT_RADIO ||
|
|
|
|
mType == NS_FORM_INPUT_RESET ||
|
2004-02-26 23:01:45 +00:00
|
|
|
mType == NS_FORM_INPUT_SUBMIT ||
|
|
|
|
mType == NS_FORM_INPUT_IMAGE)) {
|
2000-05-30 02:45:55 +00:00
|
|
|
|
2003-07-28 21:09:56 +00:00
|
|
|
nsCOMPtr<nsIDocument> doc = mDocument; // Strong in case the event kills it
|
2003-09-27 04:18:26 +00:00
|
|
|
nsCOMPtr<nsIPresContext> context;
|
|
|
|
|
|
|
|
nsIPresShell *shell = doc->GetShellAt(0);
|
|
|
|
|
|
|
|
if (shell) {
|
|
|
|
shell->GetPresContext(getter_AddRefs(context));
|
|
|
|
|
|
|
|
if (context) {
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2004-01-12 08:25:18 +00:00
|
|
|
nsMouseEvent event(NS_MOUSE_LEFT_CLICK);
|
2003-09-27 04:18:26 +00:00
|
|
|
|
|
|
|
SET_BOOLBIT(mBitField, BF_HANDLING_CLICK, PR_TRUE);
|
|
|
|
|
|
|
|
rv = HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT,
|
|
|
|
&status);
|
|
|
|
|
|
|
|
SET_BOOLBIT(mBitField, BF_HANDLING_CLICK, PR_FALSE);
|
1999-07-26 15:02:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2000-08-01 21:40:38 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
return NS_OK;
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
nsresult
|
1999-11-24 06:03:41 +00:00
|
|
|
nsHTMLInputElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
2001-05-11 21:11:38 +00:00
|
|
|
nsEvent* aEvent,
|
|
|
|
nsIDOMEvent** aDOMEvent,
|
|
|
|
PRUint32 aFlags,
|
|
|
|
nsEventStatus* aEventStatus)
|
1998-09-23 17:16:51 +00:00
|
|
|
{
|
1999-11-24 06:03:41 +00:00
|
|
|
NS_ENSURE_ARG_POINTER(aEventStatus);
|
1999-11-15 15:13:12 +00:00
|
|
|
|
1999-12-04 02:22:21 +00:00
|
|
|
// Do not process any DOM events if the element is disabled
|
|
|
|
PRBool disabled;
|
|
|
|
nsresult rv = GetDisabled(&disabled);
|
2002-12-17 04:31:21 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (disabled) {
|
|
|
|
return NS_OK;
|
1999-12-04 02:22:21 +00:00
|
|
|
}
|
2000-08-08 23:38:00 +00:00
|
|
|
|
2004-04-30 23:55:16 +00:00
|
|
|
// For some reason or another we also need to check if the style shows us
|
|
|
|
// as disabled.
|
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
|
|
|
if (formControlFrame) {
|
|
|
|
nsIFrame* formFrame = nsnull;
|
|
|
|
CallQueryInterface(formControlFrame, &formFrame);
|
|
|
|
if (formFrame) {
|
|
|
|
const nsStyleUserInterface* uiStyle = formFrame->GetStyleUserInterface();
|
|
|
|
|
|
|
|
if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
|
|
|
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) {
|
|
|
|
return NS_OK;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
2000-08-08 23:38:00 +00:00
|
|
|
}
|
|
|
|
}
|
1999-12-04 02:22:21 +00:00
|
|
|
|
2000-08-02 22:06:37 +00:00
|
|
|
//
|
2002-12-17 04:31:21 +00:00
|
|
|
// Web pages expect the value of a radio button or checkbox to be set
|
2004-04-30 23:55:16 +00:00
|
|
|
// *before* onclick and DOMActivate fire, and they expect that if they set
|
|
|
|
// the value explicitly during onclick or DOMActivate it will not be toggled
|
|
|
|
// or any such nonsense.
|
2002-12-17 04:31:21 +00:00
|
|
|
// In order to support that (bug 57137 and 58460 are examples) we toggle
|
2004-04-30 23:55:16 +00:00
|
|
|
// the checked attribute *first*, and then fire onclick. If the user
|
|
|
|
// returns false, we reset the control to the old checked value. Otherwise,
|
|
|
|
// we dispatch DOMActivate. If DOMActivate is cancelled, we also reset
|
|
|
|
// the control to the old checked value. We need to keep track of whether
|
|
|
|
// we've already toggled the state from onclick since the user could
|
|
|
|
// explicitly dispatch DOMActivate on the element.
|
2002-12-17 04:31:21 +00:00
|
|
|
//
|
|
|
|
// This is a compatibility hack.
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2004-04-30 23:55:16 +00:00
|
|
|
|
|
|
|
// Track whether we're in the "outer" HandleDOMEvent invocation
|
|
|
|
PRBool clickOrExtActivate =
|
|
|
|
(aEvent->message == NS_MOUSE_LEFT_CLICK ||
|
|
|
|
(aEvent->message == NS_DOMUI_ACTIVATE &&
|
|
|
|
!GET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE)));
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
PRBool originalCheckedValue = PR_FALSE;
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
|
|
|
|
|
2002-12-17 04:31:21 +00:00
|
|
|
if (!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
|
|
|
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
2004-04-30 23:55:16 +00:00
|
|
|
clickOrExtActivate) {
|
|
|
|
|
|
|
|
SET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED, PR_FALSE);
|
|
|
|
|
2002-12-17 04:31:21 +00:00
|
|
|
switch(mType) {
|
2000-12-10 16:05:29 +00:00
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
{
|
2002-12-17 04:31:21 +00:00
|
|
|
GetChecked(&originalCheckedValue);
|
2004-01-21 04:28:57 +00:00
|
|
|
DoSetChecked(!originalCheckedValue);
|
2004-04-30 23:55:16 +00:00
|
|
|
SET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED, PR_TRUE);
|
2000-12-10 16:05:29 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
{
|
2002-07-20 23:09:24 +00:00
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
if (container) {
|
2002-03-07 20:53:40 +00:00
|
|
|
nsAutoString name;
|
2002-08-06 04:32:57 +00:00
|
|
|
if (GetNameIfExists(name)) {
|
|
|
|
container->GetCurrentRadioButton(name,
|
|
|
|
getter_AddRefs(selectedRadioButton));
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
2002-12-17 04:31:21 +00:00
|
|
|
GetChecked(&originalCheckedValue);
|
|
|
|
if (!originalCheckedValue) {
|
2004-01-21 04:28:57 +00:00
|
|
|
DoSetChecked(PR_TRUE);
|
2004-04-30 23:55:16 +00:00
|
|
|
SET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED, PR_TRUE);
|
2000-12-10 16:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
case NS_FORM_INPUT_SUBMIT:
|
|
|
|
case NS_FORM_INPUT_IMAGE:
|
|
|
|
if(mForm) {
|
|
|
|
// tell the form that we are about to enter a click handler.
|
|
|
|
// that means that if there are scripted submissions, the
|
|
|
|
// latest one will be deferred until after the exit point of the handler.
|
|
|
|
mForm->OnSubmitClickBegin();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-12-10 16:05:29 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
} //switch
|
2000-08-02 22:06:37 +00:00
|
|
|
}
|
|
|
|
|
2001-11-07 06:29:29 +00:00
|
|
|
// If NS_EVENT_FLAG_NO_CONTENT_DISPATCH is set we will not allow content to handle
|
|
|
|
// this event. But to allow middle mouse button paste to work we must allow
|
|
|
|
// middle clicks to go to text fields anyway.
|
|
|
|
PRBool noContentDispatch = aEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
2002-12-17 04:31:21 +00:00
|
|
|
if ((mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) &&
|
2001-11-11 22:52:18 +00:00
|
|
|
aEvent->message == NS_MOUSE_MIDDLE_CLICK) {
|
2001-11-07 06:29:29 +00:00
|
|
|
aEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
|
|
|
}
|
|
|
|
|
2002-12-17 04:31:21 +00:00
|
|
|
// We must cache type because mType may change during JS event (bug 2369)
|
|
|
|
//
|
|
|
|
PRInt32 oldType = mType;
|
|
|
|
|
2000-06-09 21:13:03 +00:00
|
|
|
// Try script event handlers first if its not a focus/blur event
|
2004-06-21 23:41:30 +00:00
|
|
|
//we dont want the doc to get these
|
2004-02-10 19:36:43 +00:00
|
|
|
rv = nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent,
|
|
|
|
aDOMEvent, aFlags,
|
|
|
|
aEventStatus);
|
2001-11-07 06:29:29 +00:00
|
|
|
|
2004-04-30 23:55:16 +00:00
|
|
|
// Ideally we would make the default action for click and space just dispatch
|
|
|
|
// DOMActivate, and the default action for DOMActivate flip the checkbox/
|
|
|
|
// radio state and fire onchange. However, for backwards compatibility, we
|
|
|
|
// need to flip the state before firing click, and we need to fire click
|
|
|
|
// when space is pressed. So, we just nest the firing of DOMActivate inside
|
|
|
|
// the click event handling, and allow cancellation of DOMActivate to cancel
|
|
|
|
// the click.
|
|
|
|
if (*aEventStatus != nsEventStatus_eConsumeNoDefault &&
|
|
|
|
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
|
|
|
aEvent->message == NS_MOUSE_LEFT_CLICK && mType != NS_FORM_INPUT_TEXT) {
|
|
|
|
nsDOMUIEvent actEvent(NS_DOMUI_ACTIVATE, 1);
|
|
|
|
|
|
|
|
nsIPresShell *shell = aPresContext->GetPresShell();
|
|
|
|
if (shell) {
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
SET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE, PR_TRUE);
|
|
|
|
rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
|
|
|
|
SET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE, PR_FALSE);
|
|
|
|
|
|
|
|
// If activate is cancelled, we must do the same as when click is
|
|
|
|
// cancelled (revert the checkbox to its original value).
|
|
|
|
if (status == nsEventStatus_eConsumeNoDefault)
|
|
|
|
*aEventStatus = status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
|
|
|
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
|
|
|
clickOrExtActivate) {
|
2002-12-17 04:31:21 +00:00
|
|
|
switch(oldType) {
|
2002-11-30 00:01:21 +00:00
|
|
|
case NS_FORM_INPUT_SUBMIT:
|
|
|
|
case NS_FORM_INPUT_IMAGE:
|
|
|
|
if(mForm) {
|
|
|
|
// tell the form that we are about to exit a click handler
|
|
|
|
// so the form knows not to defer subsequent submissions
|
|
|
|
// the pending ones that were created during the handler
|
|
|
|
// will be flushed or forgoten.
|
|
|
|
mForm->OnSubmitClickEnd();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
} //switch
|
|
|
|
}
|
|
|
|
|
2001-11-07 06:29:29 +00:00
|
|
|
// Reset the flag for other content besides this text field
|
|
|
|
aEvent->flags |= noContentDispatch ? NS_EVENT_FLAG_NO_CONTENT_DISPATCH : NS_EVENT_FLAG_NONE;
|
|
|
|
|
2000-12-10 16:05:29 +00:00
|
|
|
// now check to see if the event was "cancelled"
|
2004-04-30 23:55:16 +00:00
|
|
|
if (GET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED) && clickOrExtActivate) {
|
2002-12-17 04:31:21 +00:00
|
|
|
if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
|
|
|
|
// if it was cancelled and a radio button, then set the old
|
|
|
|
// selected btn to TRUE. if it is a checkbox then set it to its
|
|
|
|
// original value
|
|
|
|
if (selectedRadioButton) {
|
|
|
|
selectedRadioButton->SetChecked(PR_TRUE);
|
|
|
|
// If this one is no longer a radio button we must reset it back to
|
|
|
|
// false to cancel the action. See how the web of hack grows?
|
|
|
|
if (mType != NS_FORM_INPUT_RADIO) {
|
2004-01-21 04:28:57 +00:00
|
|
|
DoSetChecked(PR_FALSE);
|
2002-12-17 04:31:21 +00:00
|
|
|
}
|
|
|
|
} else if (oldType == NS_FORM_INPUT_CHECKBOX) {
|
2004-01-21 04:28:57 +00:00
|
|
|
DoSetChecked(originalCheckedValue);
|
2002-12-17 04:31:21 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
FireOnChange();
|
|
|
|
#ifdef ACCESSIBILITY
|
|
|
|
// Fire an event to notify accessibility
|
|
|
|
if (mType == NS_FORM_INPUT_CHECKBOX) {
|
|
|
|
FireEventForAccessibility(aPresContext,
|
|
|
|
NS_LITERAL_STRING("CheckboxStateChange"));
|
|
|
|
} else {
|
|
|
|
FireEventForAccessibility(aPresContext,
|
|
|
|
NS_LITERAL_STRING("RadioStateChange"));
|
|
|
|
}
|
|
|
|
#endif
|
2000-12-10 16:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
2000-10-24 01:41:07 +00:00
|
|
|
|
2002-11-30 00:01:21 +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)) {
|
2002-11-30 00:01:21 +00:00
|
|
|
if (nsEventStatus_eIgnore == *aEventStatus) {
|
|
|
|
switch (aEvent->message) {
|
|
|
|
|
|
|
|
case NS_FOCUS_CONTENT:
|
|
|
|
{
|
2003-01-02 14:25:10 +00:00
|
|
|
// Check to see if focus has bubbled up from a form control's
|
|
|
|
// child textfield or button. If that's the case, don't focus
|
|
|
|
// this parent file control -- leave focus on the child.
|
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
|
|
|
if (formControlFrame && !(aFlags & NS_EVENT_FLAG_BUBBLE))
|
|
|
|
formControlFrame->SetFocus(PR_TRUE, PR_TRUE);
|
2002-11-30 00:01:21 +00:00
|
|
|
}
|
|
|
|
break; // NS_FOCUS_CONTENT
|
|
|
|
|
|
|
|
case NS_KEY_PRESS:
|
|
|
|
case NS_KEY_UP:
|
|
|
|
{
|
|
|
|
// For backwards compat, trigger checks/radios/buttons with
|
|
|
|
// space or enter (bug 25300)
|
|
|
|
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
|
|
|
|
|
|
|
if ((aEvent->message == NS_KEY_PRESS &&
|
|
|
|
keyEvent->keyCode == NS_VK_RETURN) ||
|
|
|
|
(aEvent->message == NS_KEY_UP &&
|
|
|
|
keyEvent->keyCode == NS_VK_SPACE)) {
|
2002-12-17 04:31:21 +00:00
|
|
|
switch(mType) {
|
2002-11-30 00:01:21 +00:00
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
{
|
|
|
|
// Checkbox and Radio try to submit on Enter press
|
|
|
|
if (keyEvent->keyCode != NS_VK_SPACE) {
|
2004-01-05 23:39:50 +00:00
|
|
|
MaybeSubmitForm(aPresContext);
|
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
break; // If we are submitting, do not send click event
|
2001-08-16 07:38:47 +00:00
|
|
|
}
|
2002-11-30 00:01:21 +00:00
|
|
|
// else fall through and treat Space like click...
|
2001-08-16 07:38:47 +00:00
|
|
|
}
|
2002-11-30 00:01:21 +00:00
|
|
|
case NS_FORM_INPUT_BUTTON:
|
|
|
|
case NS_FORM_INPUT_RESET:
|
|
|
|
case NS_FORM_INPUT_SUBMIT:
|
|
|
|
case NS_FORM_INPUT_IMAGE: // Bug 34418
|
|
|
|
{
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2004-01-12 08:25:18 +00:00
|
|
|
nsMouseEvent event(NS_MOUSE_LEFT_CLICK);
|
2002-11-30 00:01:21 +00:00
|
|
|
rv = HandleDOMEvent(aPresContext, &event, nsnull,
|
|
|
|
NS_EVENT_FLAG_INIT, &status);
|
|
|
|
} // case
|
|
|
|
} // switch
|
|
|
|
}
|
2002-06-04 00:44:04 +00:00
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
/*
|
2002-12-17 04:31:21 +00:00
|
|
|
* If this is input type=text, and the user hit enter, fire onChange
|
|
|
|
* and submit the form (if we are in one)
|
2002-11-30 00:01:21 +00:00
|
|
|
*
|
|
|
|
* Bug 99920, bug 109463 and bug 147850:
|
2002-12-17 04:31:21 +00:00
|
|
|
* (a) if there is a submit control in the form, click the first
|
|
|
|
* submit control in the form.
|
|
|
|
* (b) if there is just one text control in the form, submit by
|
|
|
|
* sending a submit event directly to the form
|
2002-11-30 00:01:21 +00:00
|
|
|
* (c) if there is more than one text input and no submit buttons, do
|
|
|
|
* not submit, period.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (aEvent->message == NS_KEY_PRESS &&
|
|
|
|
(keyEvent->keyCode == NS_VK_RETURN ||
|
|
|
|
keyEvent->keyCode == NS_VK_ENTER) &&
|
2002-12-17 04:31:21 +00:00
|
|
|
(mType == NS_FORM_INPUT_TEXT ||
|
2004-04-01 00:56:58 +00:00
|
|
|
mType == NS_FORM_INPUT_PASSWORD ||
|
|
|
|
mType == NS_FORM_INPUT_FILE)) {
|
|
|
|
|
|
|
|
nsIFrame* primaryFrame = GetPrimaryFrame(PR_FALSE);
|
|
|
|
if (primaryFrame) {
|
|
|
|
nsITextControlFrame* textFrame = nsnull;
|
|
|
|
CallQueryInterface(primaryFrame, &textFrame);
|
|
|
|
|
|
|
|
// Fire onChange (if necessary)
|
|
|
|
if (textFrame) {
|
|
|
|
textFrame->CheckFireOnChange();
|
2002-06-04 00:44:04 +00:00
|
|
|
}
|
2003-07-29 22:59:37 +00:00
|
|
|
}
|
2002-06-04 00:44:04 +00:00
|
|
|
|
2004-01-05 23:39:50 +00:00
|
|
|
rv = MaybeSubmitForm(aPresContext);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-06-04 00:44:04 +00:00
|
|
|
}
|
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
} break; // NS_KEY_PRESS || NS_KEY_UP
|
|
|
|
|
|
|
|
// cancel all of these events for buttons
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
|
|
|
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
|
|
|
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
|
|
|
case NS_MOUSE_RIGHT_DOUBLECLICK:
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
|
|
|
case NS_MOUSE_RIGHT_BUTTON_UP:
|
|
|
|
{
|
2002-12-17 04:31:21 +00:00
|
|
|
if (mType == NS_FORM_INPUT_BUTTON ||
|
|
|
|
mType == NS_FORM_INPUT_RESET ||
|
|
|
|
mType == NS_FORM_INPUT_SUBMIT ) {
|
2002-11-30 00:01:21 +00:00
|
|
|
nsCOMPtr<nsIDOMNSEvent> nsevent;
|
2001-12-06 06:57:03 +00:00
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
if (aDOMEvent) {
|
|
|
|
nsevent = do_QueryInterface(*aDOMEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nsevent) {
|
|
|
|
nsevent->PreventBubble();
|
|
|
|
} else {
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
}
|
2000-05-04 13:57:35 +00:00
|
|
|
}
|
|
|
|
|
2002-11-30 00:01:21 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-05-17 22:05:41 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clickOrExtActivate) {
|
|
|
|
if (mForm && (oldType == NS_FORM_INPUT_SUBMIT ||
|
|
|
|
oldType == NS_FORM_INPUT_IMAGE)) {
|
|
|
|
if (mType != NS_FORM_INPUT_SUBMIT && mType != NS_FORM_INPUT_IMAGE) {
|
|
|
|
// If the type has changed to a non-submit type, then we want to
|
|
|
|
// flush the stored submission if there is one (as if the submit()
|
|
|
|
// was allowed to succeed)
|
|
|
|
mForm->FlushPendingSubmission();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch(mType) {
|
|
|
|
case NS_FORM_INPUT_RESET:
|
|
|
|
case NS_FORM_INPUT_SUBMIT:
|
|
|
|
case NS_FORM_INPUT_IMAGE:
|
|
|
|
if (mForm) {
|
|
|
|
nsFormEvent event((mType == NS_FORM_INPUT_RESET) ?
|
|
|
|
NS_FORM_RESET : NS_FORM_SUBMIT);
|
|
|
|
event.originator = this;
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
|
|
|
|
|
|
|
nsIPresShell *presShell = aPresContext->GetPresShell();
|
|
|
|
|
|
|
|
// If |nsIPresShell::Destroy| has been called due to
|
|
|
|
// handling the event (base class HandleDOMEvent, above),
|
|
|
|
// the pres context will return a null pres shell. See
|
|
|
|
// bug 125624.
|
|
|
|
if (presShell) {
|
|
|
|
nsCOMPtr<nsIContent> form(do_QueryInterface(mForm));
|
|
|
|
presShell->HandleDOMEventWithTarget(form, &event, &status);
|
2002-12-17 04:31:21 +00:00
|
|
|
}
|
|
|
|
}
|
2004-05-17 22:05:41 +00:00
|
|
|
break;
|
2000-05-30 02:45:55 +00:00
|
|
|
|
2004-05-17 22:05:41 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
} //switch
|
|
|
|
} //click or outer activate event
|
2002-11-30 00:01:21 +00:00
|
|
|
} else {
|
2004-05-17 22:05:41 +00:00
|
|
|
if (clickOrExtActivate &&
|
2002-12-17 04:31:21 +00:00
|
|
|
(oldType == NS_FORM_INPUT_SUBMIT || oldType == NS_FORM_INPUT_IMAGE) &&
|
|
|
|
mForm) {
|
2002-11-30 00:01:21 +00:00
|
|
|
// 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
|
2002-12-17 04:31:21 +00:00
|
|
|
// be submitted immediately.
|
2002-11-30 00:01:21 +00:00
|
|
|
mForm->FlushPendingSubmission();
|
|
|
|
}
|
|
|
|
} //if
|
2000-01-11 20:33:36 +00:00
|
|
|
} // if
|
1999-07-26 15:02:19 +00:00
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
return rv;
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
1999-07-26 15:02:19 +00:00
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
void
|
2002-07-20 23:09:24 +00:00
|
|
|
nsHTMLInputElement::SetDocument(nsIDocument* aDocument, PRBool aDeep,
|
|
|
|
PRBool aCompileEventHandlers)
|
|
|
|
{
|
2003-07-24 17:10:14 +00:00
|
|
|
PRBool documentChanging = (aDocument != mDocument);
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
// SetDocument() sets the form and that takes care of form's WillRemove
|
|
|
|
// so we just have to take care of the case where we're removing from the
|
|
|
|
// document and we don't have a form
|
2003-07-24 17:10:14 +00:00
|
|
|
if (documentChanging && !mForm && mType == NS_FORM_INPUT_RADIO) {
|
2002-07-20 23:09:24 +00:00
|
|
|
WillRemoveFromRadioGroup();
|
|
|
|
}
|
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::SetDocument(aDocument, aDeep,
|
|
|
|
aCompileEventHandlers);
|
2003-07-24 17:10:14 +00:00
|
|
|
|
|
|
|
if (mType == NS_FORM_INPUT_IMAGE &&
|
2003-11-07 09:47:23 +00:00
|
|
|
documentChanging && aDocument && GetParent()) {
|
2003-07-24 17:10:14 +00:00
|
|
|
// Our base URI may have changed; claim that our URI changed, and the
|
|
|
|
// nsImageLoadingContent will decide whether a new image load is warranted.
|
|
|
|
nsAutoString uri;
|
|
|
|
nsresult result = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
|
|
|
|
if (result == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
ImageURIChanged(uri);
|
|
|
|
}
|
|
|
|
}
|
2002-07-20 23:09:24 +00:00
|
|
|
|
|
|
|
// If this is radio button which is in a form,
|
|
|
|
// and the parser is still creating the element.
|
|
|
|
if (mForm || mType != NS_FORM_INPUT_RADIO ||
|
|
|
|
GET_BOOLBIT(mBitField, BF_PARSER_CREATING)) {
|
2004-01-09 23:54:21 +00:00
|
|
|
return;
|
2002-07-20 23:09:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add radio to document if we don't have a form already (if we do it's
|
|
|
|
// already been added into that group)
|
|
|
|
if (aDocument && !mForm && mType == NS_FORM_INPUT_RADIO) {
|
|
|
|
AddedToRadioGroup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
void
|
2003-07-24 17:10:14 +00:00
|
|
|
nsHTMLInputElement::SetParent(nsIContent* aParent)
|
|
|
|
{
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::SetParent(aParent);
|
2003-07-24 17:10:14 +00:00
|
|
|
if (mType == NS_FORM_INPUT_IMAGE && aParent && mDocument) {
|
|
|
|
// Our base URI may have changed; claim that our URI changed, and the
|
|
|
|
// nsImageLoadingContent will decide whether a new image load is warranted.
|
|
|
|
nsAutoString uri;
|
|
|
|
nsresult result = GetAttr(kNameSpaceID_None, nsHTMLAtoms::src, uri);
|
|
|
|
if (result == NS_CONTENT_ATTR_HAS_VALUE) {
|
|
|
|
ImageURIChanged(uri);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
// nsIHTMLContent
|
|
|
|
|
2003-05-27 03:49:22 +00:00
|
|
|
static const nsHTMLValue::EnumTable kInputTypeTable[] = {
|
1998-09-23 17:16:51 +00:00
|
|
|
{ "button", NS_FORM_INPUT_BUTTON },
|
|
|
|
{ "checkbox", NS_FORM_INPUT_CHECKBOX },
|
|
|
|
{ "file", NS_FORM_INPUT_FILE },
|
|
|
|
{ "hidden", NS_FORM_INPUT_HIDDEN },
|
|
|
|
{ "reset", NS_FORM_INPUT_RESET },
|
|
|
|
{ "image", NS_FORM_INPUT_IMAGE },
|
|
|
|
{ "password", NS_FORM_INPUT_PASSWORD },
|
|
|
|
{ "radio", NS_FORM_INPUT_RADIO },
|
|
|
|
{ "submit", NS_FORM_INPUT_SUBMIT },
|
|
|
|
{ "text", NS_FORM_INPUT_TEXT },
|
|
|
|
{ 0 }
|
|
|
|
};
|
|
|
|
|
2004-03-04 02:06:28 +00:00
|
|
|
PRBool
|
|
|
|
nsHTMLInputElement::ParseAttribute(nsIAtom* aAttribute,
|
|
|
|
const nsAString& aValue,
|
|
|
|
nsAttrValue& aResult)
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
1998-09-23 17:16:51 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::type) {
|
2004-03-04 02:06:28 +00:00
|
|
|
// XXX ARG!! This is major evilness. ParseAttribute
|
2004-02-11 00:09:59 +00:00
|
|
|
// shouldn't set members. Override SetAttr instead
|
2004-03-04 02:06:28 +00:00
|
|
|
if (!aResult.ParseEnumValue(aValue, kInputTypeTable)) {
|
|
|
|
mType = NS_FORM_INPUT_TEXT;
|
|
|
|
return PR_FALSE;
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
|
|
|
|
mType = aResult.GetEnumValue();
|
|
|
|
if (mType == NS_FORM_INPUT_FILE) {
|
|
|
|
// If the type is being changed to file, set the element value
|
|
|
|
// to the empty string. This is for security.
|
2004-04-29 00:52:53 +00:00
|
|
|
// Call SetValueInternal so that this doesn't accidentally get caught
|
|
|
|
// in the security checks in SetValue.
|
|
|
|
SetValueInternal(EmptyString(), nsnull);
|
1999-07-24 19:55:35 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
|
|
|
|
return PR_TRUE;
|
2000-12-23 10:56:31 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::width) {
|
|
|
|
return aResult.ParseSpecialIntValue(aValue, PR_TRUE, PR_FALSE);
|
2000-12-23 10:56:31 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::height) {
|
|
|
|
return aResult.ParseSpecialIntValue(aValue, PR_TRUE, PR_FALSE);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::maxlength) {
|
|
|
|
return aResult.ParseIntWithBounds(aValue, 0);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::size) {
|
|
|
|
return aResult.ParseIntWithBounds(aValue, 0);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::tabindex) {
|
|
|
|
return aResult.ParseIntWithBounds(aValue, 0, 32767);
|
2000-12-23 10:56:31 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::border) {
|
|
|
|
return aResult.ParseIntWithBounds(aValue, 0);
|
|
|
|
}
|
|
|
|
if (aAttribute == nsHTMLAtoms::align) {
|
|
|
|
return ParseAlignValue(aValue, aResult);
|
1998-09-23 17:16:51 +00:00
|
|
|
}
|
2004-03-04 02:06:28 +00:00
|
|
|
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
|
2003-08-11 21:53:24 +00:00
|
|
|
// We have to call |ParseImageAttribute| unconditionally since we
|
|
|
|
// don't know if we're going to have a type="image" attribute yet,
|
|
|
|
// (or could have it set dynamically in the future). See bug
|
|
|
|
// 214077.
|
2004-03-04 02:06:28 +00:00
|
|
|
return PR_TRUE;
|
1998-11-07 05:27:39 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2004-03-04 02:06:28 +00:00
|
|
|
return nsGenericHTMLElement::ParseAttribute(aAttribute, aValue, aResult);
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-09-02 23:53:16 +00:00
|
|
|
nsHTMLInputElement::AttributeToString(nsIAtom* aAttribute,
|
1998-12-20 01:21:23 +00:00
|
|
|
const nsHTMLValue& aValue,
|
2002-03-23 23:04:39 +00:00
|
|
|
nsAString& aResult) const
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
1998-09-23 17:16:51 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::type) {
|
|
|
|
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
|
2000-05-09 13:56:40 +00:00
|
|
|
// The DOM spec says that input types should be capitalized but
|
|
|
|
// AFAIK all existing browsers return the type in lower case,
|
|
|
|
// http://bugzilla.mozilla.org/show_bug.cgi?id=32369 is the bug
|
2002-09-26 08:18:42 +00:00
|
|
|
// about this problem. -- jst@netscape.com
|
2001-12-04 21:12:15 +00:00
|
|
|
// Update. The DOM spec will be changed to have input types be
|
|
|
|
// all-lowercase. See
|
|
|
|
// http://bugzilla.mozilla.org/show_bug.cgi?id=113174#c12
|
|
|
|
// -- bzbarsky@mit.edu
|
2000-05-09 13:56:40 +00:00
|
|
|
|
2003-01-21 21:24:16 +00:00
|
|
|
aValue.EnumValueToString(kInputTypeTable, aResult);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1998-09-23 17:16:51 +00:00
|
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
|
|
|
}
|
2000-01-25 15:38:49 +00:00
|
|
|
else if (aAttribute == nsHTMLAtoms::align) {
|
|
|
|
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
|
2002-09-26 08:18:42 +00:00
|
|
|
AlignValueToString(aValue, aResult);
|
2000-01-25 15:38:49 +00:00
|
|
|
return NS_CONTENT_ATTR_HAS_VALUE;
|
|
|
|
}
|
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
return nsGenericHTMLFormElement::AttributeToString(aAttribute, aValue,
|
|
|
|
aResult);
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
2004-06-26 16:49:33 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetType(nsAString& aValue)
|
|
|
|
{
|
|
|
|
const nsHTMLValue::EnumTable *table = kInputTypeTable;
|
|
|
|
|
|
|
|
while (table->tag) {
|
|
|
|
if (mType == table->value) {
|
|
|
|
CopyUTF8toUTF16(table->tag, aValue);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
++table;
|
|
|
|
}
|
|
|
|
|
2004-06-27 06:09:46 +00:00
|
|
|
NS_ERROR("Shouldn't get here!");
|
2004-06-26 16:49:33 +00:00
|
|
|
|
|
|
|
aValue.Truncate();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetType(const nsAString& aValue)
|
|
|
|
{
|
|
|
|
return SetAttrHelper(nsHTMLAtoms::type, aValue);
|
|
|
|
}
|
|
|
|
|
1998-09-05 04:00:06 +00:00
|
|
|
static void
|
2004-01-26 19:22:05 +00:00
|
|
|
MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
|
2001-05-31 22:19:43 +00:00
|
|
|
nsRuleData* aData)
|
1998-09-01 01:27:08 +00:00
|
|
|
{
|
2004-04-13 16:45:59 +00:00
|
|
|
const nsAttrValue* value = aAttributes->GetAttr(nsHTMLAtoms::type);
|
|
|
|
if (value && value->Type() == nsAttrValue::eEnum &&
|
|
|
|
value->GetEnumValue() == NS_FORM_INPUT_IMAGE) {
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::MapImageBorderAttributeInto(aAttributes, aData);
|
|
|
|
nsGenericHTMLFormElement::MapImageMarginAttributeInto(aAttributes, aData);
|
|
|
|
nsGenericHTMLFormElement::MapImageSizeAttributesInto(aAttributes, aData);
|
2002-12-27 00:41:52 +00:00
|
|
|
// Images treat align as "float"
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::MapImageAlignAttributeInto(aAttributes, aData);
|
2002-09-26 08:18:42 +00:00
|
|
|
} else {
|
2002-12-27 00:41:52 +00:00
|
|
|
// Everything else treats align as "text-align"
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::MapDivAlignAttributeInto(aAttributes, aData);
|
2002-12-27 00:41:52 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData);
|
1998-09-01 01:27:08 +00:00
|
|
|
}
|
|
|
|
|
1999-07-07 01:24:40 +00:00
|
|
|
NS_IMETHODIMP
|
2003-07-11 21:16:12 +00:00
|
|
|
nsHTMLInputElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
|
|
|
PRInt32 aModType,
|
|
|
|
nsChangeHint& aHint) const
|
1999-07-07 01:24:40 +00:00
|
|
|
{
|
2003-07-11 21:16:12 +00:00
|
|
|
nsresult rv =
|
2004-02-10 19:36:43 +00:00
|
|
|
nsGenericHTMLFormElement::GetAttributeChangeHint(aAttribute, aModType,
|
|
|
|
aHint);
|
2003-07-11 21:16:12 +00:00
|
|
|
if (aAttribute == nsHTMLAtoms::type) {
|
|
|
|
NS_UpdateHint(aHint, NS_STYLE_HINT_FRAMECHANGE);
|
|
|
|
} else if (aAttribute == nsHTMLAtoms::value) {
|
|
|
|
NS_UpdateHint(aHint, NS_STYLE_HINT_REFLOW);
|
|
|
|
} else if (aAttribute == nsHTMLAtoms::size &&
|
|
|
|
(mType == NS_FORM_INPUT_TEXT ||
|
|
|
|
mType == NS_FORM_INPUT_PASSWORD)) {
|
|
|
|
NS_UpdateHint(aHint, NS_STYLE_HINT_REFLOW);
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP_(PRBool)
|
2004-02-25 21:04:50 +00:00
|
|
|
nsHTMLInputElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
2003-07-11 21:16:12 +00:00
|
|
|
{
|
2004-02-25 21:04:50 +00:00
|
|
|
static const MappedAttributeEntry attributes[] = {
|
2003-07-11 21:16:12 +00:00
|
|
|
{ &nsHTMLAtoms::align },
|
|
|
|
{ &nsHTMLAtoms::type },
|
|
|
|
{ nsnull },
|
2003-04-16 20:54:20 +00:00
|
|
|
};
|
|
|
|
|
2004-02-25 21:04:50 +00:00
|
|
|
static const MappedAttributeEntry* const map[] = {
|
2003-04-16 20:54:20 +00:00
|
|
|
attributes,
|
|
|
|
sCommonAttributeMap,
|
2003-07-11 21:16:12 +00:00
|
|
|
sImageMarginSizeAttributeMap,
|
2003-04-16 20:54:20 +00:00
|
|
|
sImageBorderAttributeMap,
|
|
|
|
};
|
|
|
|
|
2003-07-11 21:16:12 +00:00
|
|
|
return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
|
1999-07-07 01:24:40 +00:00
|
|
|
}
|
|
|
|
|
1998-09-05 04:00:06 +00:00
|
|
|
NS_IMETHODIMP
|
2001-05-31 22:19:43 +00:00
|
|
|
nsHTMLInputElement::GetAttributeMappingFunction(nsMapRuleToAttributesFunc& aMapRuleFunc) const
|
1998-09-05 04:00:06 +00:00
|
|
|
{
|
2001-05-31 22:19:43 +00:00
|
|
|
aMapRuleFunc = &MapAttributesIntoRule;
|
1998-09-05 04:00:06 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2000-06-23 14:12:24 +00:00
|
|
|
|
1999-12-01 15:12:49 +00:00
|
|
|
// Controllers Methods
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1999-12-01 15:12:49 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetControllers(nsIControllers** aResult)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
|
|
|
|
//XXX: what about type "file"?
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD)
|
1999-12-01 15:12:49 +00:00
|
|
|
{
|
|
|
|
if (!mControllers)
|
|
|
|
{
|
2000-02-16 01:41:17 +00:00
|
|
|
nsresult rv;
|
2002-12-17 13:29:39 +00:00
|
|
|
mControllers = do_CreateInstance(kXULControllersCID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2000-12-23 10:56:31 +00:00
|
|
|
nsCOMPtr<nsIController>
|
|
|
|
controller(do_CreateInstance("@mozilla.org/editor/editorcontroller;1",
|
|
|
|
&rv));
|
2002-12-17 13:29:39 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
1999-12-15 03:54:52 +00:00
|
|
|
mControllers->AppendController(controller);
|
1999-12-01 15:12:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*aResult = mControllers;
|
|
|
|
NS_IF_ADDREF(*aResult);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
1999-12-01 15:12:49 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2000-04-13 05:15:59 +00:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetTextLength(PRInt32* aTextLength)
|
|
|
|
{
|
2001-11-06 09:10:07 +00:00
|
|
|
nsAutoString val;
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2001-11-06 09:10:07 +00:00
|
|
|
nsresult rv = GetValue(val);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2001-11-06 09:10:07 +00:00
|
|
|
*aTextLength = val.Length();
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2001-11-06 09:10:07 +00:00
|
|
|
return rv;
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLInputElement::SetSelectionRange(PRInt32 aSelectionStart,
|
|
|
|
PRInt32 aSelectionEnd)
|
2000-04-13 05:15:59 +00:00
|
|
|
{
|
2003-01-09 06:06:17 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
2003-01-09 06:06:17 +00:00
|
|
|
nsITextControlFrame* textControlFrame = nsnull;
|
|
|
|
CallQueryInterface(formControlFrame, &textControlFrame);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2000-04-13 05:15:59 +00:00
|
|
|
if (textControlFrame)
|
2003-01-09 06:06:17 +00:00
|
|
|
rv = textControlFrame->SetSelectionRange(aSelectionStart, aSelectionEnd);
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-01-09 06:06:17 +00:00
|
|
|
return rv;
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetSelectionStart(PRInt32* aSelectionStart)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSelectionStart);
|
|
|
|
|
|
|
|
PRInt32 selEnd;
|
|
|
|
return GetSelectionRange(aSelectionStart, &selEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetSelectionStart(PRInt32 aSelectionStart)
|
|
|
|
{
|
2003-01-09 06:06:17 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
2003-01-09 06:06:17 +00:00
|
|
|
nsITextControlFrame* textControlFrame = nsnull;
|
|
|
|
CallQueryInterface(formControlFrame, &textControlFrame);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2000-04-13 05:15:59 +00:00
|
|
|
if (textControlFrame)
|
2003-01-09 06:06:17 +00:00
|
|
|
rv = textControlFrame->SetSelectionStart(aSelectionStart);
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-01-09 06:06:17 +00:00
|
|
|
return rv;
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetSelectionEnd(PRInt32* aSelectionEnd)
|
|
|
|
{
|
|
|
|
NS_ENSURE_ARG_POINTER(aSelectionEnd);
|
|
|
|
|
|
|
|
PRInt32 selStart;
|
|
|
|
return GetSelectionRange(&selStart, aSelectionEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SetSelectionEnd(PRInt32 aSelectionEnd)
|
|
|
|
{
|
2003-01-09 06:06:17 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
2003-01-09 06:06:17 +00:00
|
|
|
nsITextControlFrame* textControlFrame = nsnull;
|
|
|
|
CallQueryInterface(formControlFrame, &textControlFrame);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2000-04-13 05:15:59 +00:00
|
|
|
if (textControlFrame)
|
2003-01-09 06:06:17 +00:00
|
|
|
rv = textControlFrame->SetSelectionEnd(aSelectionEnd);
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-01-09 06:06:17 +00:00
|
|
|
return rv;
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
2000-12-23 10:56:31 +00:00
|
|
|
nsHTMLInputElement::GetSelectionRange(PRInt32* aSelectionStart,
|
|
|
|
PRInt32* aSelectionEnd)
|
2000-04-13 05:15:59 +00:00
|
|
|
{
|
2003-01-09 06:06:17 +00:00
|
|
|
nsresult rv = NS_ERROR_FAILURE;
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
|
|
|
if (formControlFrame) {
|
2003-01-09 06:06:17 +00:00
|
|
|
nsITextControlFrame* textControlFrame = nsnull;
|
|
|
|
CallQueryInterface(formControlFrame, &textControlFrame);
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2000-04-13 05:15:59 +00:00
|
|
|
if (textControlFrame)
|
2003-01-09 06:06:17 +00:00
|
|
|
rv = textControlFrame->GetSelectionRange(aSelectionStart, aSelectionEnd);
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
2000-12-23 10:56:31 +00:00
|
|
|
|
2003-01-09 06:06:17 +00:00
|
|
|
return rv;
|
2000-04-13 05:15:59 +00:00
|
|
|
}
|
|
|
|
|
2002-12-17 23:38:04 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::GetPhonetic(nsAString& aPhonetic)
|
|
|
|
{
|
|
|
|
aPhonetic.Truncate(0);
|
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
|
|
|
|
|
|
|
if (formControlFrame) {
|
|
|
|
nsCOMPtr<nsIPhonetic>
|
|
|
|
phonetic(do_QueryInterface(formControlFrame));
|
|
|
|
|
|
|
|
if (phonetic)
|
|
|
|
phonetic->GetPhonetic(aPhonetic);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-17 03:13:07 +00:00
|
|
|
#ifdef ACCESSIBILITY
|
2001-05-11 21:11:38 +00:00
|
|
|
nsresult
|
|
|
|
nsHTMLInputElement::FireEventForAccessibility(nsIPresContext* aPresContext,
|
2002-03-23 23:04:39 +00:00
|
|
|
const nsAString& aEventType)
|
2001-05-11 21:11:38 +00:00
|
|
|
{
|
2003-03-05 03:20:17 +00:00
|
|
|
nsCOMPtr<nsIDOMEvent> event;
|
|
|
|
nsCOMPtr<nsIEventListenerManager> manager;
|
2003-04-16 20:54:20 +00:00
|
|
|
GetListenerManager(getter_AddRefs(manager));
|
2003-03-05 03:20:17 +00:00
|
|
|
if (manager &&
|
|
|
|
NS_SUCCEEDED(manager->CreateEvent(aPresContext, nsnull, NS_LITERAL_STRING("Events"), getter_AddRefs(event)))) {
|
|
|
|
event->InitEvent(aEventType, PR_TRUE, PR_TRUE);
|
2004-02-27 17:17:37 +00:00
|
|
|
|
2003-03-05 03:20:17 +00:00
|
|
|
PRBool noDefault;
|
2004-02-27 17:17:37 +00:00
|
|
|
nsISupports *target = NS_STATIC_CAST(nsIDOMHTMLInputElement*, this);
|
|
|
|
aPresContext->EventStateManager()->DispatchNewEvent(target, event,
|
|
|
|
&noDefault);
|
2003-03-05 03:20:17 +00:00
|
|
|
}
|
2001-05-11 21:11:38 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2001-08-17 03:13:07 +00:00
|
|
|
#endif
|
2001-11-02 07:40:01 +00:00
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLInputElement::Reset()
|
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2001-12-12 07:31:15 +00:00
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
2001-11-05 06:50:21 +00:00
|
|
|
|
2002-12-18 23:38:09 +00:00
|
|
|
switch (mType) {
|
2001-11-02 07:40:01 +00:00
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
{
|
|
|
|
PRBool resetVal;
|
|
|
|
GetDefaultChecked(&resetVal);
|
2004-01-21 04:28:57 +00:00
|
|
|
rv = DoSetChecked(resetVal);
|
2002-03-07 20:53:40 +00:00
|
|
|
SetCheckedChanged(PR_FALSE);
|
2001-11-02 07:40:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NS_FORM_INPUT_PASSWORD:
|
|
|
|
case NS_FORM_INPUT_TEXT:
|
|
|
|
{
|
2001-11-05 06:50:21 +00:00
|
|
|
// If the frame is there, we have to set the value so that it will show
|
|
|
|
// up.
|
|
|
|
if (formControlFrame) {
|
|
|
|
nsAutoString resetVal;
|
|
|
|
GetDefaultValue(resetVal);
|
|
|
|
rv = SetValue(resetVal);
|
|
|
|
}
|
|
|
|
SetValueChanged(PR_FALSE);
|
2001-11-02 07:40:01 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case NS_FORM_INPUT_FILE:
|
|
|
|
{
|
|
|
|
// Resetting it to blank should not perform security check
|
2004-01-29 22:04:45 +00:00
|
|
|
rv = SetValueInternal(EmptyString(), nsnull);
|
2001-11-02 07:40:01 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-06-12 06:35:11 +00:00
|
|
|
// Value is the same as defaultValue for hidden inputs
|
|
|
|
case NS_FORM_INPUT_HIDDEN:
|
2001-11-02 07:40:01 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2001-11-05 06:50:21 +00:00
|
|
|
|
|
|
|
// Notify frame that it has been reset
|
|
|
|
if (formControlFrame) {
|
|
|
|
formControlFrame->OnContentReset();
|
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
|
|
|
|
nsIContent* aSubmitElement)
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
2002-02-16 01:19:24 +00:00
|
|
|
nsresult rv = NS_OK;
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Disabled elements don't submit
|
|
|
|
//
|
2001-11-02 07:40:01 +00:00
|
|
|
PRBool disabled;
|
2002-02-16 01:19:24 +00:00
|
|
|
rv = GetDisabled(&disabled);
|
|
|
|
if (NS_FAILED(rv) || disabled) {
|
|
|
|
return rv;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// For type=reset, and type=button, we just never submit, period.
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_RESET || mType == NS_FORM_INPUT_BUTTON) {
|
2002-02-16 01:19:24 +00:00
|
|
|
return rv;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// For type=image and type=button, we only submit if we were the button
|
|
|
|
// pressed
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if ((mType == NS_FORM_INPUT_SUBMIT || mType == NS_FORM_INPUT_IMAGE)
|
2002-02-16 01:19:24 +00:00
|
|
|
&& aSubmitElement != this) {
|
|
|
|
return rv;
|
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// For type=radio and type=checkbox, we only submit if checked=true
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_RADIO || mType == NS_FORM_INPUT_CHECKBOX) {
|
2002-02-16 01:19:24 +00:00
|
|
|
PRBool checked;
|
|
|
|
rv = GetChecked(&checked);
|
|
|
|
if (NS_FAILED(rv) || !checked) {
|
|
|
|
return rv;
|
2002-01-24 19:08:57 +00:00
|
|
|
}
|
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Get the name
|
|
|
|
//
|
|
|
|
nsAutoString name;
|
|
|
|
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
PRBool nameThere = (rv != NS_CONTENT_ATTR_NOT_THERE);
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Submit .x, .y for input type=image
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_IMAGE) {
|
2002-02-16 01:19:24 +00:00
|
|
|
// Go to the frame to find out where it was clicked. This is the only
|
|
|
|
// case where I can actually see using the frame, because you're talking
|
|
|
|
// about a value--mouse click--that is rightfully the domain of the frame.
|
|
|
|
//
|
|
|
|
// If the frame isn't there or isn't an ImageControlFrame, then we're not
|
|
|
|
// submitting these values no matter *how* nicely you ask.
|
|
|
|
PRInt32 clickedX;
|
|
|
|
PRInt32 clickedY;
|
|
|
|
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
|
|
|
|
|
2002-08-17 05:42:55 +00:00
|
|
|
nsIImageControlFrame* imageControlFrame = nsnull;
|
2002-08-27 22:00:26 +00:00
|
|
|
if (formControlFrame) {
|
|
|
|
CallQueryInterface(formControlFrame, &imageControlFrame);
|
2004-01-22 03:26:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
nsAutoString xVal;
|
|
|
|
nsAutoString yVal;
|
|
|
|
|
|
|
|
if (imageControlFrame) {
|
|
|
|
imageControlFrame->GetClickedX(&clickedX);
|
|
|
|
imageControlFrame->GetClickedY(&clickedY);
|
|
|
|
|
|
|
|
// Convert the values to strings for submission
|
|
|
|
xVal.AppendInt(clickedX);
|
|
|
|
yVal.AppendInt(clickedY);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!name.IsEmpty()) {
|
|
|
|
aFormSubmission->AddNameValuePair(this,
|
|
|
|
name + NS_LITERAL_STRING(".x"), xVal);
|
|
|
|
aFormSubmission->AddNameValuePair(this,
|
|
|
|
name + NS_LITERAL_STRING(".y"), yVal);
|
|
|
|
} else {
|
|
|
|
// If the Image Element has no name, simply return x and y
|
|
|
|
// to Nav and IE compatability.
|
|
|
|
aFormSubmission->AddNameValuePair(this, NS_LITERAL_STRING("x"), xVal);
|
|
|
|
aFormSubmission->AddNameValuePair(this, NS_LITERAL_STRING("y"), yVal);
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Submit name=value
|
|
|
|
//
|
|
|
|
|
|
|
|
// If name not there, don't submit
|
|
|
|
if (!nameThere) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the value
|
|
|
|
nsAutoString value;
|
|
|
|
rv = GetValue(value);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Submit file if it's input type=file and this encoding method accepts files
|
|
|
|
//
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_FILE) {
|
2002-02-16 01:19:24 +00:00
|
|
|
//
|
|
|
|
// Open the file
|
|
|
|
//
|
2002-09-16 06:00:08 +00:00
|
|
|
nsCOMPtr<nsIFile> file;
|
|
|
|
|
2003-07-14 07:37:39 +00:00
|
|
|
if (StringBeginsWith(value, NS_LITERAL_STRING("file:"),
|
|
|
|
nsCaseInsensitiveStringComparator())) {
|
2002-09-16 06:00:08 +00:00
|
|
|
// Converts the URL string into the corresponding nsIFile if possible.
|
|
|
|
// A local file will be created if the URL string begins with file://.
|
|
|
|
rv = NS_GetFileFromURLSpec(NS_ConvertUCS2toUTF8(value),
|
|
|
|
getter_AddRefs(file));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file) {
|
|
|
|
// this is no "file://", try as local file
|
|
|
|
nsCOMPtr<nsILocalFile> localFile;
|
|
|
|
rv = NS_NewLocalFile(value, PR_FALSE, getter_AddRefs(localFile));
|
|
|
|
file = localFile;
|
|
|
|
}
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get the leaf path name (to be submitted as the value)
|
|
|
|
//
|
2002-05-07 23:07:19 +00:00
|
|
|
nsAutoString filename;
|
|
|
|
rv = file->GetLeafName(filename);
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2004-02-24 02:54:12 +00:00
|
|
|
if (NS_SUCCEEDED(rv) && !filename.IsEmpty()) {
|
2004-01-09 23:54:21 +00:00
|
|
|
PRBool acceptsFiles = aFormSubmission->AcceptsFiles();
|
2002-02-16 01:19:24 +00:00
|
|
|
|
|
|
|
if (acceptsFiles) {
|
|
|
|
//
|
|
|
|
// Get content type
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIMIMEService> MIMEService =
|
|
|
|
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
nsCAutoString contentType;
|
2004-04-15 20:56:37 +00:00
|
|
|
rv = MIMEService->GetTypeFromFile(file, contentType);
|
|
|
|
if (NS_FAILED(rv)) {
|
2004-06-17 00:13:25 +00:00
|
|
|
contentType.AssignLiteral("application/octet-stream");
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get input stream
|
|
|
|
//
|
2002-04-18 22:02:09 +00:00
|
|
|
nsCOMPtr<nsIInputStream> fileStream;
|
|
|
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream),
|
|
|
|
file, -1, -1,
|
|
|
|
nsIFileInputStream::CLOSE_ON_EOF |
|
|
|
|
nsIFileInputStream::REOPEN_ON_REWIND);
|
|
|
|
if (fileStream) {
|
|
|
|
//
|
|
|
|
// Create buffered stream (for efficiency)
|
|
|
|
//
|
2002-02-16 01:19:24 +00:00
|
|
|
nsCOMPtr<nsIInputStream> bufferedStream;
|
|
|
|
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
|
2002-04-18 22:02:09 +00:00
|
|
|
fileStream, 8192);
|
2002-02-16 01:19:24 +00:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-04-18 22:02:09 +00:00
|
|
|
if (bufferedStream) {
|
|
|
|
//
|
|
|
|
// Submit
|
|
|
|
//
|
|
|
|
aFormSubmission->AddNameFilePair(this, name, filename,
|
|
|
|
bufferedStream, contentType,
|
|
|
|
PR_FALSE);
|
|
|
|
return rv;
|
|
|
|
}
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// If we don't submit as a file, at least submit the truncated filename.
|
|
|
|
//
|
2002-04-07 00:17:56 +00:00
|
|
|
aFormSubmission->AddNameFilePair(this, name, filename,
|
|
|
|
nsnull, NS_LITERAL_CSTRING("application/octet-stream"),
|
|
|
|
PR_FALSE);
|
|
|
|
return rv;
|
2004-02-24 02:54:12 +00:00
|
|
|
} else {
|
|
|
|
// Ignore error returns from GetLeafName. See bug 199053
|
|
|
|
rv = NS_OK;
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
2002-04-07 00:17:56 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// If we can't even make a truncated filename, submit empty string
|
|
|
|
// rather than sending everything
|
|
|
|
//
|
|
|
|
aFormSubmission->AddNameFilePair(this, name, value,
|
|
|
|
nsnull, NS_LITERAL_CSTRING("application/octet-stream"),
|
|
|
|
PR_FALSE);
|
|
|
|
return rv;
|
2002-02-16 01:19:24 +00:00
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
|
2002-04-07 00:17:56 +00:00
|
|
|
// Submit
|
|
|
|
// (for type=image, only submit if value is non-null)
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType != NS_FORM_INPUT_IMAGE || !value.IsEmpty()) {
|
2002-04-07 00:17:56 +00:00
|
|
|
rv = aFormSubmission->AddNameValuePair(this, name, value);
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
return rv;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
2002-02-16 01:19:24 +00:00
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
NS_IMETHODIMP
|
2002-03-31 10:14:01 +00:00
|
|
|
nsHTMLInputElement::SaveState()
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2002-03-31 10:14:01 +00:00
|
|
|
nsCOMPtr<nsIPresState> state;
|
2002-12-18 23:38:09 +00:00
|
|
|
switch (mType) {
|
2002-03-07 20:53:40 +00:00
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
{
|
|
|
|
PRBool checked = PR_FALSE;
|
|
|
|
GetChecked(&checked);
|
2002-03-31 10:14:01 +00:00
|
|
|
PRBool defaultChecked = PR_FALSE;
|
|
|
|
GetDefaultChecked(&defaultChecked);
|
|
|
|
// Only save if checked != defaultChecked (bug 62713)
|
|
|
|
// (always save if it's a radio button so that the checked
|
|
|
|
// state of all radio buttons is restored)
|
2002-12-18 23:38:09 +00:00
|
|
|
if (mType == NS_FORM_INPUT_RADIO || checked != defaultChecked) {
|
2002-03-31 10:14:01 +00:00
|
|
|
rv = GetPrimaryPresState(this, getter_AddRefs(state));
|
|
|
|
if (state) {
|
|
|
|
if (checked) {
|
|
|
|
rv = state->SetStateProperty(NS_LITERAL_STRING("checked"),
|
|
|
|
NS_LITERAL_STRING("t"));
|
|
|
|
} else {
|
|
|
|
rv = state->SetStateProperty(NS_LITERAL_STRING("checked"),
|
|
|
|
NS_LITERAL_STRING("f"));
|
|
|
|
}
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "checked save failed!");
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
// Never save passwords in session history
|
|
|
|
case NS_FORM_INPUT_PASSWORD:
|
|
|
|
break;
|
|
|
|
case NS_FORM_INPUT_TEXT:
|
|
|
|
case NS_FORM_INPUT_FILE:
|
2002-06-12 06:35:11 +00:00
|
|
|
case NS_FORM_INPUT_HIDDEN:
|
2002-03-07 20:53:40 +00:00
|
|
|
{
|
2002-03-31 10:14:01 +00:00
|
|
|
if (GET_BOOLBIT(mBitField, BF_VALUE_CHANGED)) {
|
|
|
|
rv = GetPrimaryPresState(this, getter_AddRefs(state));
|
|
|
|
if (state) {
|
|
|
|
nsAutoString value;
|
|
|
|
GetValue(value);
|
|
|
|
rv = nsLinebreakConverter::ConvertStringLineBreaks(
|
|
|
|
value,
|
|
|
|
nsLinebreakConverter::eLinebreakPlatform,
|
|
|
|
nsLinebreakConverter::eLinebreakContent);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Converting linebreaks failed!");
|
|
|
|
rv = state->SetStateProperty(NS_LITERAL_STRING("v"), value);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "value save failed!");
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
break;
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
}
|
2003-11-10 05:52:29 +00:00
|
|
|
|
|
|
|
if (GET_BOOLBIT(mBitField, BF_DISABLED_CHANGED)) {
|
|
|
|
rv |= GetPrimaryPresState(this, getter_AddRefs(state));
|
|
|
|
if (state) {
|
|
|
|
PRBool disabled;
|
|
|
|
GetDisabled(&disabled);
|
|
|
|
if (disabled) {
|
|
|
|
rv |= state->SetStateProperty(NS_LITERAL_STRING("disabled"),
|
|
|
|
NS_LITERAL_STRING("t"));
|
|
|
|
} else {
|
|
|
|
rv |= state->SetStateProperty(NS_LITERAL_STRING("disabled"),
|
|
|
|
NS_LITERAL_STRING("f"));
|
|
|
|
}
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "disabled save failed!");
|
|
|
|
}
|
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2004-01-09 23:54:21 +00:00
|
|
|
void
|
2002-03-31 10:14:01 +00:00
|
|
|
nsHTMLInputElement::DoneCreatingElement()
|
|
|
|
{
|
|
|
|
SET_BOOLBIT(mBitField, BF_PARSER_CREATING, PR_FALSE);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Restore state for checkbox, radio, text and file
|
|
|
|
//
|
|
|
|
PRBool restored = PR_FALSE;
|
|
|
|
switch (mType) {
|
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
case NS_FORM_INPUT_TEXT:
|
|
|
|
case NS_FORM_INPUT_FILE:
|
2002-06-12 06:35:11 +00:00
|
|
|
case NS_FORM_INPUT_HIDDEN:
|
2002-03-31 10:14:01 +00:00
|
|
|
restored = RestoreFormControlState(this, this);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// If restore does not occur, we initialize .checked using the CHECKED
|
|
|
|
// property.
|
|
|
|
//
|
|
|
|
if (!restored && GET_BOOLBIT(mBitField, BF_SHOULD_INIT_CHECKED)) {
|
|
|
|
PRBool resetVal;
|
|
|
|
GetDefaultChecked(&resetVal);
|
2004-01-21 04:28:57 +00:00
|
|
|
DoSetChecked(resetVal, PR_FALSE);
|
2002-03-31 10:14:01 +00:00
|
|
|
SetCheckedChanged(PR_FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_BOOLBIT(mBitField, BF_SHOULD_INIT_CHECKED, PR_FALSE);
|
2002-07-20 23:09:24 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// If the radio button is not in a form, we can add it to
|
|
|
|
// radio group in document here, otherwise we will miss it.
|
|
|
|
//
|
|
|
|
if (!mForm && mType == NS_FORM_INPUT_RADIO)
|
2004-01-21 04:28:57 +00:00
|
|
|
AddedToRadioGroup(PR_FALSE);
|
2002-03-31 10:14:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsHTMLInputElement::RestoreState(nsIPresState* aState)
|
2001-11-02 07:40:01 +00:00
|
|
|
{
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2002-12-18 23:38:09 +00:00
|
|
|
switch (mType) {
|
2002-03-07 20:53:40 +00:00
|
|
|
case NS_FORM_INPUT_CHECKBOX:
|
|
|
|
case NS_FORM_INPUT_RADIO:
|
|
|
|
{
|
|
|
|
nsAutoString checked;
|
|
|
|
rv = aState->GetStateProperty(NS_LITERAL_STRING("checked"), checked);
|
2003-11-10 05:52:29 +00:00
|
|
|
if (rv == NS_STATE_PROPERTY_EXISTS) {
|
2004-05-22 22:15:22 +00:00
|
|
|
DoSetChecked(checked.EqualsLiteral("t"), PR_FALSE);
|
2003-11-10 05:52:29 +00:00
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-11-02 07:40:01 +00:00
|
|
|
case NS_FORM_INPUT_TEXT:
|
|
|
|
case NS_FORM_INPUT_FILE:
|
2002-06-12 06:35:11 +00:00
|
|
|
case NS_FORM_INPUT_HIDDEN:
|
2002-03-07 20:53:40 +00:00
|
|
|
{
|
|
|
|
nsAutoString value;
|
2002-03-31 10:14:01 +00:00
|
|
|
rv = aState->GetStateProperty(NS_LITERAL_STRING("v"), value);
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "value restore failed!");
|
2003-11-10 05:52:29 +00:00
|
|
|
if (rv == NS_STATE_PROPERTY_EXISTS) {
|
|
|
|
SetValueInternal(value, nsnull);
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2003-11-10 05:52:29 +00:00
|
|
|
|
|
|
|
nsAutoString disabled;
|
|
|
|
nsresult rv2 = aState->GetStateProperty(NS_LITERAL_STRING("disabled"), disabled);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv2), "disabled restore failed!");
|
|
|
|
if (rv2 == NS_STATE_PROPERTY_EXISTS) {
|
2004-05-22 22:15:22 +00:00
|
|
|
SetDisabled(disabled.EqualsLiteral("t"));
|
2003-11-10 05:52:29 +00:00
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
|
2003-11-10 05:52:29 +00:00
|
|
|
if (NS_FAILED(rv|rv2)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
2004-02-11 21:31:53 +00:00
|
|
|
PRBool
|
|
|
|
nsHTMLInputElement::AllowDrop()
|
|
|
|
{
|
|
|
|
// Allow drop on anything other than file inputs.
|
|
|
|
|
|
|
|
return mType != NS_FORM_INPUT_FILE;
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Radio group stuff
|
|
|
|
*/
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2004-01-21 04:28:57 +00:00
|
|
|
nsHTMLInputElement::AddedToRadioGroup(PRBool aNotify)
|
2002-03-07 20:53:40 +00:00
|
|
|
{
|
2004-01-21 04:28:57 +00:00
|
|
|
if (aNotify)
|
|
|
|
aNotify = GET_BOOLBIT(mBitField, BF_PARSER_CREATING) != 0;
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2002-07-20 23:09:24 +00:00
|
|
|
// If the input element is not in a form and
|
|
|
|
// not in a document, we just need to return.
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2003-11-07 17:07:03 +00:00
|
|
|
if (!mForm && !(mDocument && GetParent())) {
|
2002-03-07 20:53:40 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// If the input element is checked, and we add it to the group, it will
|
|
|
|
// deselect whatever is currently selected in that group
|
|
|
|
//
|
|
|
|
PRBool checked;
|
|
|
|
GetChecked(&checked);
|
|
|
|
if (checked) {
|
|
|
|
//
|
|
|
|
// If it is checked, call "RadioSetChecked" to perform the selection/
|
|
|
|
// deselection ritual. This has the side effect of repainting the
|
|
|
|
// radio button, but as adding a checked radio button into the group
|
|
|
|
// should not be that common an occurrence, I think we can live with
|
|
|
|
// that.
|
|
|
|
//
|
2004-01-21 04:28:57 +00:00
|
|
|
RadioSetChecked(aNotify);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// For integrity purposes, we have to ensure that "checkedChanged" is
|
|
|
|
// the same for this new element as for all the others in the group
|
|
|
|
//
|
|
|
|
PRBool checkedChanged = PR_FALSE;
|
|
|
|
nsCOMPtr<nsIRadioVisitor> visitor;
|
|
|
|
nsresult rv = NS_GetRadioGetCheckedChangedVisitor(&checkedChanged, this,
|
|
|
|
getter_AddRefs(visitor));
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2002-07-20 23:09:24 +00:00
|
|
|
|
|
|
|
VisitGroup(visitor);
|
2002-03-07 20:53:40 +00:00
|
|
|
SetCheckedChangedInternal(checkedChanged);
|
2002-07-20 23:09:24 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Add the radio to the radio group container.
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
if (container) {
|
|
|
|
nsAutoString name;
|
2002-08-06 04:32:57 +00:00
|
|
|
if (GetNameIfExists(name)) {
|
|
|
|
container->AddToRadioGroup(name, NS_STATIC_CAST(nsIFormControl*, this));
|
|
|
|
}
|
2002-07-20 23:09:24 +00:00
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2002-07-20 23:09:24 +00:00
|
|
|
nsHTMLInputElement::WillRemoveFromRadioGroup()
|
2002-03-07 20:53:40 +00:00
|
|
|
{
|
|
|
|
//
|
2002-07-20 23:09:24 +00:00
|
|
|
// If the input element is not in a form and
|
|
|
|
// not in a document, we just need to return.
|
2002-03-07 20:53:40 +00:00
|
|
|
//
|
2003-11-07 17:07:03 +00:00
|
|
|
if (!mForm && !(mDocument && GetParent())) {
|
2002-03-07 20:53:40 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// If this button was checked, we need to notify the group that there is no
|
|
|
|
// longer a selected radio button
|
|
|
|
//
|
|
|
|
PRBool checked = PR_FALSE;
|
|
|
|
GetChecked(&checked);
|
|
|
|
|
2002-07-20 23:09:24 +00:00
|
|
|
nsAutoString name;
|
|
|
|
PRBool gotName = PR_FALSE;
|
2002-03-07 20:53:40 +00:00
|
|
|
if (checked) {
|
2002-07-20 23:09:24 +00:00
|
|
|
if (!gotName) {
|
2002-08-06 04:32:57 +00:00
|
|
|
if (!GetNameIfExists(name)) {
|
|
|
|
// If the name doesn't exist, nothing is going to happen anyway
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-07-20 23:09:24 +00:00
|
|
|
gotName = PR_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
if (container) {
|
|
|
|
container->SetCurrentRadioButton(name, nsnull);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Remove this radio from its group in the container
|
|
|
|
//
|
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
if (container) {
|
|
|
|
if (!gotName) {
|
2002-08-06 04:32:57 +00:00
|
|
|
if (!GetNameIfExists(name)) {
|
|
|
|
// If the name doesn't exist, nothing is going to happen anyway
|
|
|
|
return NS_OK;
|
|
|
|
}
|
2002-07-20 23:09:24 +00:00
|
|
|
gotName = PR_TRUE;
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
2002-07-20 23:09:24 +00:00
|
|
|
container->RemoveFromRadioGroup(name,
|
|
|
|
NS_STATIC_CAST(nsIFormControl*, this));
|
2001-11-02 07:40:01 +00:00
|
|
|
}
|
|
|
|
|
2002-03-07 20:53:40 +00:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
nsHTMLInputElement::VisitGroup(nsIRadioVisitor* aVisitor)
|
|
|
|
{
|
2002-07-23 03:58:49 +00:00
|
|
|
nsresult rv = NS_OK;
|
2002-07-20 23:09:24 +00:00
|
|
|
nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer();
|
|
|
|
if (container) {
|
2002-03-07 20:53:40 +00:00
|
|
|
nsAutoString name;
|
2002-08-06 04:32:57 +00:00
|
|
|
if (GetNameIfExists(name)) {
|
|
|
|
rv = container->WalkRadioGroup(name, aVisitor);
|
|
|
|
} else {
|
|
|
|
PRBool stop;
|
|
|
|
aVisitor->Visit(this, &stop);
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
} else {
|
2002-07-20 23:09:24 +00:00
|
|
|
PRBool stop;
|
|
|
|
aVisitor->Visit(this, &stop);
|
2002-03-07 20:53:40 +00:00
|
|
|
}
|
2001-11-02 07:40:01 +00:00
|
|
|
return rv;
|
|
|
|
}
|
2002-03-07 20:53:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Visitor classes
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// CLASS nsRadioVisitor
|
|
|
|
//
|
|
|
|
// (this is the superclass of the others)
|
|
|
|
//
|
|
|
|
class nsRadioVisitor : public nsIRadioVisitor {
|
|
|
|
public:
|
2003-01-08 19:24:38 +00:00
|
|
|
nsRadioVisitor() { }
|
2002-03-07 20:53:40 +00:00
|
|
|
virtual ~nsRadioVisitor() { };
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(nsRadioVisitor)
|
|
|
|
NS_IMPL_RELEASE(nsRadioVisitor)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsRadioVisitor)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIRadioVisitor)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
|
|
NS_INTERFACE_MAP_END
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// CLASS nsRadioSetCheckedChangedVisitor
|
|
|
|
//
|
|
|
|
class nsRadioSetCheckedChangedVisitor : public nsRadioVisitor {
|
|
|
|
public:
|
|
|
|
nsRadioSetCheckedChangedVisitor(PRBool aCheckedChanged) :
|
|
|
|
nsRadioVisitor(), mCheckedChanged(aCheckedChanged)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
virtual ~nsRadioSetCheckedChangedVisitor() { }
|
|
|
|
|
|
|
|
NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop)
|
|
|
|
{
|
|
|
|
nsCOMPtr<nsIRadioControlElement> radio(do_QueryInterface(aRadio));
|
|
|
|
NS_ASSERTION(radio, "Visit() passed a null button (or non-radio)!");
|
|
|
|
radio->SetCheckedChangedInternal(mCheckedChanged);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PRPackedBool mCheckedChanged;
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// CLASS nsRadioGetCheckedChangedVisitor
|
|
|
|
//
|
|
|
|
class nsRadioGetCheckedChangedVisitor : public nsRadioVisitor {
|
|
|
|
public:
|
|
|
|
nsRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged,
|
|
|
|
nsIFormControl* aExcludeElement) :
|
|
|
|
nsRadioVisitor(),
|
|
|
|
mCheckedChanged(aCheckedChanged),
|
|
|
|
mExcludeElement(aExcludeElement)
|
|
|
|
{ }
|
|
|
|
|
|
|
|
virtual ~nsRadioGetCheckedChangedVisitor() { }
|
|
|
|
|
|
|
|
NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop)
|
|
|
|
{
|
|
|
|
if (aRadio == mExcludeElement) {
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsCOMPtr<nsIRadioControlElement> radio(do_QueryInterface(aRadio));
|
|
|
|
NS_ASSERTION(radio, "Visit() passed a null button (or non-radio)!");
|
|
|
|
radio->GetCheckedChanged(mCheckedChanged);
|
|
|
|
*aStop = PR_TRUE;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PRBool* mCheckedChanged;
|
|
|
|
nsIFormControl* mExcludeElement;
|
|
|
|
};
|
|
|
|
|
2003-03-05 15:08:41 +00:00
|
|
|
nsresult
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_GetRadioSetCheckedChangedVisitor(PRBool aCheckedChanged,
|
|
|
|
nsIRadioVisitor** aVisitor)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// These are static so that we don't have to keep creating new visitors for
|
|
|
|
// such an ordinary process all the time. There are only two possibilities
|
|
|
|
// for this visitor: set to true, and set to false.
|
|
|
|
//
|
|
|
|
static nsIRadioVisitor* visitorTrue = nsnull;
|
|
|
|
static nsIRadioVisitor* visitorFalse = nsnull;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get the visitor that sets them to true
|
|
|
|
//
|
|
|
|
if (aCheckedChanged) {
|
|
|
|
if (!visitorTrue) {
|
|
|
|
visitorTrue = new nsRadioSetCheckedChangedVisitor(PR_TRUE);
|
|
|
|
if (!visitorTrue) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
NS_ADDREF(visitorTrue);
|
|
|
|
}
|
|
|
|
*aVisitor = visitorTrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get the visitor that sets them to false
|
|
|
|
//
|
|
|
|
if (!aCheckedChanged) {
|
|
|
|
if (!visitorFalse) {
|
|
|
|
visitorFalse = new nsRadioSetCheckedChangedVisitor(PR_FALSE);
|
|
|
|
if (!visitorFalse) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
NS_ADDREF(visitorFalse);
|
|
|
|
}
|
|
|
|
*aVisitor = visitorFalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_ADDREF(*aVisitor);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2003-03-05 15:08:41 +00:00
|
|
|
nsresult
|
2002-03-07 20:53:40 +00:00
|
|
|
NS_GetRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged,
|
|
|
|
nsIFormControl* aExcludeElement,
|
|
|
|
nsIRadioVisitor** aVisitor)
|
|
|
|
{
|
|
|
|
*aVisitor = new nsRadioGetCheckedChangedVisitor(aCheckedChanged,
|
|
|
|
aExcludeElement);
|
|
|
|
if (!*aVisitor) {
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
NS_ADDREF(*aVisitor);
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|