form submission on carriage return in some cases; replaced NS_RELEASE with NS_IF_RELEASE in nsFrame destructor

This commit is contained in:
karnaze%netscape.com 1998-08-04 18:19:51 +00:00
parent f6940bf50a
commit f76f781af8
9 changed files with 98 additions and 4 deletions

View File

@ -179,7 +179,7 @@ nsFrame::nsFrame(nsIContent* aContent, nsIFrame* aParent)
nsFrame::~nsFrame()
{
NS_RELEASE(mContent);
NS_IF_RELEASE(mContent);
NS_IF_RELEASE(mStyleContext);
if (nsnull != mView) {
// Break association between view and frame

View File

@ -36,6 +36,7 @@ public:
virtual PRBool GetChecked(PRBool aGetInitialValue) const = 0;
virtual void SetChecked(PRBool aState, PRBool aSetInitialValue) = 0;
virtual PRBool GetCanSubmit() const = 0;
/**
* Get the form manager which manages this control.
* @return the form manager
@ -94,6 +95,11 @@ public:
*/
virtual void Reset() = 0;
/**
* Set this control to be able to cause a form submission if aFlag is true.
*/
virtual void SetCanSubmit(PRBool aFlag) = 0;
/**
* Set this content of this control. This is a no-op for controls that do not
* have content set explicitly.

View File

@ -914,15 +914,28 @@ void nsForm::Init(PRBool aReinit)
RemoveRadioGroups();
// determine which radio buttons belong to which radio groups, unnamed radio buttons
// don't go into any group since they can't be submitted
// don't go into any group since they can't be submitted. Determine which controls
// are capable of form submission.
PRInt32 submitCount = 0;
PRInt32 nonSubmitCount = 0;
nsIFormControl* textControl = nsnull;
int numControls = GetFormControlCount();
for (int i = 0; i < numControls; i++) {
nsIFormControl* control = (nsIFormControl *)GetFormControlAt(i);
nsString name;
PRBool hasName = control->GetName(name);
nsString type;
control->GetType(type);
if (hasName && (type.Equals(*nsInputRadio::kTYPE))) {
if (type.EqualsIgnoreCase("submit")) { // XXX make constant
submitCount++;
} else if (!type.EqualsIgnoreCase("hidden")) { // hidden doesn't count, XXX make constant
nonSubmitCount++;
}
if (type.EqualsIgnoreCase("text")) { // XXX make constants
textControl = control;
}
if (hasName && (type.Equals(*nsInputRadio::kTYPE))) { // XXX make constant consisten with above
int numGroups = mRadioGroups.Count();
PRBool added = PR_FALSE;
nsInputRadioGroup* group;
@ -952,6 +965,10 @@ void nsForm::Init(PRBool aReinit)
}
}
}
if ( ((0 == submitCount) || (1 == submitCount)) &&
(1 == nonSubmitCount) && (nsnull != textControl) ) {
textControl->SetCanSubmit(PR_TRUE);
}
}
void

View File

@ -53,6 +53,7 @@ nsInput::nsInput(nsIAtom* aTag, nsIFormManager* aManager)
mAlign = ALIGN_UNSET;
mLastClickPoint.x = -1;
mLastClickPoint.y = -1;
mCanSubmit = PR_FALSE;
}
nsInput::~nsInput()
@ -78,6 +79,16 @@ void nsInput::SetClickPoint(nscoord aX, nscoord aY)
mLastClickPoint.y = aY;
}
PRBool nsInput::GetCanSubmit() const
{
return mCanSubmit;
}
void nsInput::SetCanSubmit(PRBool aFlag)
{
mCanSubmit = aFlag;
}
void nsInput::SetContent(const nsString& aValue)
{
if (nsnull == mValue) {
@ -517,3 +528,13 @@ PRBool nsInput::AggInputControl::GetContent(nsString& aResult) const
{
return GET_OUTER()->GetContent(aResult);
}
void nsInput::AggInputControl::SetCanSubmit(PRBool aFlag)
{
GET_OUTER()->SetCanSubmit(aFlag);
}
PRBool nsInput::AggInputControl::GetCanSubmit() const
{
return GET_OUTER()->GetCanSubmit();
}

View File

@ -65,6 +65,8 @@ public:
// nsIFormControl methods
virtual PRBool GetCanSubmit() const;
virtual PRBool GetContent(nsString& aResult) const;
/**
@ -97,6 +99,8 @@ public:
*/
virtual void Reset();
virtual void SetCanSubmit(PRBool aFlag);
virtual void SetContent(const nsString& aValue);
/**
@ -170,6 +174,7 @@ protected:
nsISupports* mWidgetSupports;
nsIFormManager* mFormMan;
nsPoint mLastClickPoint;
PRBool mCanSubmit;
void CacheAttribute(const nsString& aValue, nsString*& aLoc);
void CacheAttribute(const nsString& aValue, PRInt32 aMinValue, PRInt32& aLoc);
@ -194,6 +199,7 @@ protected:
NS_DECL_ISUPPORTS
// nsIFormControl
virtual PRBool GetCanSubmit() const;
virtual PRBool GetContent(nsString& aResult) const;
virtual PRBool GetName(nsString& aName) const;
virtual void GetType(nsString& aType) const;
@ -201,6 +207,7 @@ protected:
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
virtual void SetCanSubmit(PRBool aFlag);
virtual void SetContent(const nsString& aValue);
virtual void SetFormManager(nsIFormManager* aFormMan, PRBool aDecrementRef = PR_TRUE);
virtual nsIFormManager* GetFormManager() const;

View File

@ -409,6 +409,14 @@ NS_METHOD nsInputFrame::HandleEvent(nsIPresContext& aPresContext,
case NS_MOUSE_EXIT:
mLastMouseState = eMouseNone;
break;
case NS_KEY_DOWN:
if (NS_KEY_EVENT == aEvent->eventStructType) {
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
if (NS_VK_RETURN == keyEvent->keyCode) {
EnterPressed(aPresContext);
}
}
break;
}
aEventStatus = nsEventStatus_eConsumeDoDefault;
return NS_OK;

View File

@ -144,6 +144,11 @@ public:
*/
virtual nsresult GetWidget(nsIView* aView, nsIWidget** aWidget);
/**
* Respond to a enter key being pressed
*/
virtual void EnterPressed(nsIPresContext& aPresContext) {}
/**
* Respond to a mouse click (e.g. mouse enter, mouse down, mouse up)
*/

View File

@ -35,6 +35,9 @@
#include "nsHTMLForms.h"
#include "nsIStyleContext.h"
#include "nsFont.h"
#include "nsDOMEvent.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
class nsInputTextFrame : public nsInputFrame {
public:
@ -49,6 +52,8 @@ public:
virtual const nsIID& GetIID();
virtual void EnterPressed(nsIPresContext& aPresContext) ;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
@ -169,6 +174,31 @@ nsInputTextFrame::GetTextType()
return type;
}
void
nsInputTextFrame::EnterPressed(nsIPresContext& aPresContext)
{
nsInputText* text = (nsInputText *)mContent;
nsIFormManager* formMan = text->GetFormManager();
if (nsnull != formMan) {
nsInputTextType type = text->GetTextType();
// a form with one text area causes a submit when the enter key is pressed
// XXX this logic should be in the form manager, but then it needs to be passed
// enough to trigger the dom event.
if ((kInputText_Text == type) && text->GetCanSubmit()) {
nsEventStatus mStatus;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
nsIFormControl* control;
mContent->QueryInterface(kIFormControlIID, (void**)&control);
formMan->OnSubmit(&aPresContext, this, control);
}
}
NS_RELEASE(formMan);
}
void
nsInputTextFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,

View File

@ -28,10 +28,10 @@ SELECT#select1 {
<INPUT TYPE="TEXT" NAME="p" SIZE=15 MAXLENGTH=80>
<INPUT TYPE="submit" VALUE="Search">
<INPUT TYPE="HIDDEN" NAME="a" VALUE="n">
&nbsp;&nbsp;password:&nbsp;&nbsp;<INPUT TYPE="PASSWORD">
</FORM>
<BR><BR>
<FORM METHOD="POST" ACTION="http://www.mcp.com/cgi-bin/post-query" NAME="echo">
password:&nbsp;&nbsp;<INPUT TYPE="PASSWORD"> <BR>
<textarea name=a rows=4 cols=10 value="a textarea">a textarea</textarea>
&nbsp;&nbsp;
<textarea name=a id=textarea1 value="a textarea">another textarea