diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index 365e426029a..5bc9d24db5a 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -84,7 +84,7 @@ nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) } PRBool -nsFileControlFrame::IsSuccessful() +nsFileControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) { nsAutoString name; return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h index 3e38ee85048..3f990bcf69f 100644 --- a/mozilla/layout/forms/nsFileControlFrame.h +++ b/mozilla/layout/forms/nsFileControlFrame.h @@ -54,7 +54,7 @@ public: void SetBrowseFrame(nsButtonControlFrame* aFrame) { mBrowseFrame = aFrame; } NS_IMETHOD GetName(nsString* aName); virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } - virtual PRBool IsSuccessful(); + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual void Reset(); NS_IMETHOD GetType(PRInt32* aType) const; void SetFocus(PRBool aOn, PRBool aRepaint); diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index 83e2ea11c44..bcd77b9e425 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -206,6 +206,14 @@ nsFormControlFrame::DidReflow(nsIPresContext& aPresContext, return rv; } +NS_IMETHODIMP +nsFormControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // add ourself as an nsIFormControlFrame + nsFormFrame::AddFormControlFrame(aPresContext, *this); + return NS_OK; +} + NS_METHOD nsFormControlFrame::Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -491,7 +499,7 @@ nsFormControlFrame::GetValue(nsString* aResult) } PRBool -nsFormControlFrame::IsSuccessful() +nsFormControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) { nsAutoString name; return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); diff --git a/mozilla/layout/forms/nsFormControlFrame.h b/mozilla/layout/forms/nsFormControlFrame.h index 09e440a1dc7..23feac79091 100644 --- a/mozilla/layout/forms/nsFormControlFrame.h +++ b/mozilla/layout/forms/nsFormControlFrame.h @@ -111,6 +111,8 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus); @@ -175,7 +177,7 @@ public: void SetColors(nsIPresContext& aPresContext); virtual void Reset(); - virtual PRBool IsSuccessful(); + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); /** * Perform opertations before the widget associated with this frame has been diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp index 32c0ed5a6dc..1e2e94e37eb 100644 --- a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp @@ -81,7 +81,7 @@ public: NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); - virtual PRBool IsSuccessful(); + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); NS_IMETHOD GetType(PRInt32* aType) const; NS_IMETHOD GetName(nsString* aName); NS_IMETHOD GetValue(nsString* aName); @@ -281,14 +281,16 @@ nsHTMLButtonControlFrame::GetValue(nsString* aResult) } PRBool -nsHTMLButtonControlFrame::IsSuccessful() +nsHTMLButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) { - nsAutoString name; - return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); + if (this == (aSubmitter)) { + nsAutoString name; + return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); + } else { + return PR_FALSE; + } } - - void nsHTMLButtonControlFrame::MouseClicked(nsIPresContext* aPresContext) { @@ -525,12 +527,14 @@ nsHTMLButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, NS_IMETHODIMP nsHTMLButtonControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { + // add ourself as an nsIFormControlFrame + nsFormFrame::AddFormControlFrame(aPresContext, *this); + // create our view, we need a view to grab the mouse nsIView* view; GetView(view); if (!view) { - nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, - (void **)&view); + nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); nsIPresShell *presShell = aPresContext.GetShell(); nsIViewManager *viewMan = presShell->GetViewManager(); NS_RELEASE(presShell); diff --git a/mozilla/layout/forms/nsTextControlFrame.cpp b/mozilla/layout/forms/nsTextControlFrame.cpp index 43eb46188ef..db0a649a714 100644 --- a/mozilla/layout/forms/nsTextControlFrame.cpp +++ b/mozilla/layout/forms/nsTextControlFrame.cpp @@ -114,7 +114,7 @@ nsTextControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext, if (NS_FORM_TEXTAREA == type) { padding = (nscoord)(40 * aCharWidth / 100); } else { - padding = (nscoord)(55 * aCharWidth / 100); + padding = (nscoord)(95 * aCharWidth / 100); } nscoord min = NSIntPixelsToTwips(3, aPixToTwip); if (padding > min) { @@ -191,9 +191,9 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext, if (NS_CONTENT_ATTR_HAS_VALUE != GetSize(&width)) { width = 20; } - if (eCompatibility_NavQuirks == mode) { - width += 1; - } + //if (eCompatibility_NavQuirks == mode) { + // width += 1; + //} nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull, width, PR_FALSE, nsnull, 1); CalculateSize(aPresContext, this, styleSize, textSpec, size, diff --git a/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp index fc662e8f7f7..080d4c37b96 100644 --- a/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsButtonControlFrame.cpp @@ -68,6 +68,15 @@ nsButtonControlFrame::GetDefaultLabel(nsString& aString) } } +PRBool +nsButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) +{ + if (this == (aSubmitter)) { + return nsFormControlFrame::IsSuccessful(aSubmitter); + } else { + return PR_FALSE; + } +} PRInt32 nsButtonControlFrame::GetMaxNumValues() diff --git a/mozilla/layout/html/forms/src/nsButtonControlFrame.h b/mozilla/layout/html/forms/src/nsButtonControlFrame.h index 588a261f995..c3ba116ac64 100644 --- a/mozilla/layout/html/forms/src/nsButtonControlFrame.h +++ b/mozilla/layout/html/forms/src/nsButtonControlFrame.h @@ -57,6 +57,8 @@ public: nsFileControlFrame* GetFileControlFrame() { return mFileControlFrame; } void SetFileControlFrame(nsFileControlFrame* aFrame) { mFileControlFrame = aFrame; } void GetDefaultLabel(nsString& aLabel); + + PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual PRInt32 GetMaxNumValues(); virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index 365e426029a..5bc9d24db5a 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -84,7 +84,7 @@ nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) } PRBool -nsFileControlFrame::IsSuccessful() +nsFileControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) { nsAutoString name; return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h index 3e38ee85048..3f990bcf69f 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h @@ -54,7 +54,7 @@ public: void SetBrowseFrame(nsButtonControlFrame* aFrame) { mBrowseFrame = aFrame; } NS_IMETHOD GetName(nsString* aName); virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } - virtual PRBool IsSuccessful(); + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual void Reset(); NS_IMETHOD GetType(PRInt32* aType) const; void SetFocus(PRBool aOn, PRBool aRepaint); diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index 83e2ea11c44..bcd77b9e425 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -206,6 +206,14 @@ nsFormControlFrame::DidReflow(nsIPresContext& aPresContext, return rv; } +NS_IMETHODIMP +nsFormControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // add ourself as an nsIFormControlFrame + nsFormFrame::AddFormControlFrame(aPresContext, *this); + return NS_OK; +} + NS_METHOD nsFormControlFrame::Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -491,7 +499,7 @@ nsFormControlFrame::GetValue(nsString* aResult) } PRBool -nsFormControlFrame::IsSuccessful() +nsFormControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) { nsAutoString name; return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.h b/mozilla/layout/html/forms/src/nsFormControlFrame.h index 09e440a1dc7..23feac79091 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.h @@ -111,6 +111,8 @@ public: nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD DidReflow(nsIPresContext& aPresContext, nsDidReflowStatus aStatus); @@ -175,7 +177,7 @@ public: void SetColors(nsIPresContext& aPresContext); virtual void Reset(); - virtual PRBool IsSuccessful(); + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); /** * Perform opertations before the widget associated with this frame has been diff --git a/mozilla/layout/html/forms/src/nsFormFrame.cpp b/mozilla/layout/html/forms/src/nsFormFrame.cpp index 49cdd35fc7c..0720d22dc73 100644 --- a/mozilla/layout/html/forms/src/nsFormFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormFrame.cpp @@ -16,6 +16,7 @@ * Reserved. */ #include "nsFormFrame.h" +#include "nsIFormControlFrame.h" #include "nsFormControlFrame.h" #include "nsFileControlFrame.h" #include "nsRadioControlFrame.h" @@ -57,12 +58,17 @@ static NS_DEFINE_IID(kIFormManagerIID, NS_IFORMMANAGER_IID); static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID); +static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID); static NS_DEFINE_IID(kIDOMNSHTMLFormElementIID, NS_IDOMNSHTMLFORMELEMENT_IID); static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); +static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID); + + +nsFormFrameTable* nsFormFrame::gFormFrameTable = new nsFormFrameTable(); NS_IMETHODIMP nsFormFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) @@ -89,7 +95,6 @@ nsrefcnt nsFormFrame::Release(void) nsFormFrame::nsFormFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsLeafFrame(aContent, aParentFrame) { - mInited = PR_FALSE; mTextSubmitter = nsnull; } @@ -199,6 +204,20 @@ nsFormFrame::GetEnctype(PRInt32* aEnctype) return result; } +NS_IMETHODIMP +nsFormFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + nsresult result = NS_OK; + nsIDOMHTMLFormElement* content = nsnull; + if (mContent) { + nsresult result = mContent->QueryInterface(kIDOMHTMLFormElementIID, (void**)&content); + if ((NS_OK == result) && (nsnull != content)) { + nsFormFrame::PutFormFrame(aPresContext, *content, *this); + } + } + return result; +} + NS_IMETHODIMP nsFormFrame::Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, @@ -206,9 +225,6 @@ nsFormFrame::Reflow(nsIPresContext& aPresContext, nsReflowStatus& aStatus) { GetDesiredSize(&aPresContext, aReflowState, aDesiredSize); - if (!mInited) { - Init(aPresContext, PR_TRUE); - } aStatus = NS_FRAME_COMPLETE; return NS_OK; } @@ -234,108 +250,86 @@ void nsFormFrame::RemoveRadioGroups() mRadioGroups.Clear(); } -void nsFormFrame::Init(nsIPresContext& aPresContext, PRBool aReinit) +void nsFormFrame::AddFormControlFrame(nsIPresContext& aPresContext, nsIFrame& aFrame) { - if (mInited && !aReinit) { + nsIFormControlFrame* fcFrame = nsnull; + nsresult result = aFrame.QueryInterface(kIFormControlFrameIID, (void**)&fcFrame); + if ((NS_OK != result) || (nsnull == fcFrame)) { return; } - PRUint32 numControls = mFormControls.Count(); - nsIPresShell* presShell = aPresContext.GetShell(); - // first time - add the controls - if ((0 == numControls) && mContent) { - nsIForm* form = nsnull; - nsresult result = mContent->QueryInterface(kIFormIID, (void**)&form); - if ((NS_OK == result) && form) { - form->GetElementCount(&numControls); - for (PRUint32 childX = 0; childX < numControls; childX++) { - nsIFormControl* formControl; - form->GetElementAt(childX, &formControl); - if (formControl) { - nsIContent* content = nsnull; - result = formControl->QueryInterface(kIContentIID, (void**)&content); - if ((NS_OK == result) && content) { - nsIFrame* frame = presShell->FindFrameWithContent(content); - if (frame) { - nsIFormControlFrame* fcFrame = nsnull; - result = frame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame); - if ((NS_OK == result) && fcFrame) { - mFormControls.AppendElement(fcFrame); - fcFrame->SetFormFrame(this); - } - } - NS_RELEASE(content); - } - NS_RELEASE(formControl); + nsIContent* iContent = nsnull; + aFrame.GetContent(iContent); + if (nsnull != iContent) { + nsIFormControl* formControl = nsnull; + result = iContent->QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && (nsnull != formControl)) { + nsIDOMHTMLFormElement* formElem = nsnull; + result = formControl->GetForm(&formElem); + if (nsnull != formElem) { + nsFormFrame* formFrame = nsFormFrame::GetFormFrame(aPresContext, *formElem); + if (nsnull != formFrame) { + formFrame->AddFormControlFrame(*fcFrame); + fcFrame->SetFormFrame(formFrame); } + NS_RELEASE(formElem); } - NS_RELEASE(form); + NS_RELEASE(formControl); } + NS_RELEASE(iContent); } - NS_RELEASE(presShell); +} - RemoveRadioGroups(); +void nsFormFrame::AddFormControlFrame(nsIFormControlFrame& aFrame) +{ + mFormControls.AppendElement(&aFrame); // determine which radio buttons belong to which radio groups, unnamed radio buttons // don't go into any group since they can't be submitted. Determine which controls // are capable of form submission. - PRInt32 textCount = 0; - nsIFormControlFrame* textFrame = nsnull; - numControls = mFormControls.Count(); - for (PRUint32 i = 0; i < numControls; i++) { - nsIFormControlFrame* fcFrame = (nsIFormControlFrame *)mFormControls.ElementAt(i); - nsString name; - name.SetLength(0); - fcFrame->GetName(&name); - PRBool hasName = name.Length() > 0; - PRInt32 type; - fcFrame->GetType(&type); + nsString name; + name.SetLength(0); + aFrame.GetName(&name); + PRBool hasName = name.Length() > 0; + PRInt32 type; + aFrame.GetType(&type); - // count text for determining "return" submission - if (NS_FORM_INPUT_TEXT == type) { - textCount++; - textFrame = fcFrame; - } + // a solo text control can be a submitter (if return is hit) + if (NS_FORM_INPUT_TEXT == type) { + mTextSubmitter = (nsnull == mTextSubmitter) ? &aFrame : nsnull; + } - // radio group processing - if (hasName && (NS_FORM_INPUT_RADIO == type)) { - nsRadioControlFrame* radioFrame = (nsRadioControlFrame*)fcFrame; - int numGroups = mRadioGroups.Count(); - PRBool added = PR_FALSE; - nsRadioControlGroup* group; - for (int j = 0; j < numGroups; j++) { - group = (nsRadioControlGroup *) mRadioGroups.ElementAt(j); - nsString groupName; - group->GetName(groupName); - if (groupName.Equals(name)) { - group->AddRadio(radioFrame); - added = PR_TRUE; - break; - } - } - if (!added) { - group = new nsRadioControlGroup(name); - mRadioGroups.AppendElement(group); + // radio group processing + if (hasName && (NS_FORM_INPUT_RADIO == type)) { + nsRadioControlFrame* radioFrame = (nsRadioControlFrame*)&aFrame; + int numGroups = mRadioGroups.Count(); + PRBool added = PR_FALSE; + nsRadioControlGroup* group; + for (int j = 0; j < numGroups; j++) { + group = (nsRadioControlGroup *) mRadioGroups.ElementAt(j); + nsString groupName; + group->GetName(groupName); + if (groupName.Equals(name)) { group->AddRadio(radioFrame); - } - // allow only one checked radio button - if (radioFrame->GetChecked(PR_TRUE)) { - if (nsnull == group->GetCheckedRadio()) { - group->SetCheckedRadio(radioFrame); - } - else { - radioFrame->SetChecked(PR_FALSE, PR_TRUE); - } + added = PR_TRUE; + break; } } + if (!added) { + group = new nsRadioControlGroup(name); + mRadioGroups.AppendElement(group); + group->AddRadio(radioFrame); + } + // allow only one checked radio button + if (radioFrame->GetChecked(PR_TRUE)) { + if (nsnull == group->GetCheckedRadio()) { + group->SetCheckedRadio(radioFrame); + } else { + radioFrame->SetChecked(PR_FALSE, PR_TRUE); + } + } } - - // if there is only one text field, it can submit on "return" - if (1 == textCount) { - mTextSubmitter = textFrame; - } - mInited = PR_TRUE; } void @@ -405,11 +399,14 @@ nsFormFrame::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame) // if method is "" (not specified) use "get" as default PRBool isPost = (NS_FORM_METHOD_POST == method) || !isURLEncoded; + nsIFormControlFrame* fcFrame = nsnull; + aFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame); + if (isURLEncoded) { - ProcessAsURLEncoded(isPost, data); + ProcessAsURLEncoded(isPost, data, fcFrame); } else { - ProcessAsMultipart(data); + ProcessAsMultipart(data, fcFrame); } @@ -476,16 +473,17 @@ void URLEncode(char* aInString, char* aOutString) char* outChar = aOutString; for (char* inChar = aInString; *inChar; inChar++) { if(' ' == *inChar) { // convert space to + - *outChar++ = '+'; - } else if ( (((*inChar - '0') >= 0) && (('9' - *inChar) >= 0)) || // don't conver - (((*inChar - 'a') >= 0) && (('z' - *inChar) >= 0)) || // alphanumeric - (((*inChar - 'A') >= 0) && (('Z' - *inChar) >= 0)) ) { - *outChar++ = *inChar; - } else { // convert all else to hex - *outChar++ = '%'; + *outChar++ = '+'; + } else if ( (((*inChar - '0') >= 0) && (('9' - *inChar) >= 0)) || // don't conver alphanumeric + (((*inChar - 'a') >= 0) && (('z' - *inChar) >= 0)) || // or '.' or '_' + (((*inChar - 'A') >= 0) && (('Z' - *inChar) >= 0)) || + ('.' == *inChar) || ('_' == *inChar)) { + *outChar++ = *inChar; + } else { // convert all else to hex + *outChar++ = '%'; *outChar++ = toHex[(*inChar >> 4) & 0x0F]; *outChar++ = toHex[*inChar & 0x0F]; - } + } } *outChar = 0; // terminate the string } @@ -502,7 +500,7 @@ nsString* URLEncode(nsString& aString) } #define CRLF "\015\012" -void nsFormFrame::ProcessAsURLEncoded(PRBool isPost, nsString& aData) +void nsFormFrame::ProcessAsURLEncoded(PRBool isPost, nsString& aData, nsIFormControlFrame* aFrame) { nsString buf; PRBool firstTime = PR_TRUE; @@ -511,7 +509,7 @@ void nsFormFrame::ProcessAsURLEncoded(PRBool isPost, nsString& aData) // collect and encode the data from the children controls for (PRUint32 childX = 0; childX < numChildren; childX++) { nsIFormControlFrame* child = (nsIFormControlFrame*) mFormControls.ElementAt(childX); - if (child && child->IsSuccessful()) { + if (child && child->IsSuccessful(aFrame)) { PRInt32 numValues = 0; PRInt32 maxNumValues = child->GetMaxNumValues(); if (maxNumValues <= 0) { @@ -673,7 +671,7 @@ void nsFormFrame::Temp_GetContentType(char* aPathName, char* aContentType) #define MULTIPART "multipart/form-data" #define END "--" -void nsFormFrame::ProcessAsMultipart(nsString& aData) +void nsFormFrame::ProcessAsMultipart(nsString& aData, nsIFormControlFrame* aFrame) { aData.SetLength(0); char buffer[BUFSIZE]; @@ -714,7 +712,7 @@ void nsFormFrame::ProcessAsMultipart(nsString& aData) if (child) { PRInt32 type; child->GetType(&type); - if (child->IsSuccessful()) { + if (child->IsSuccessful(aFrame)) { PRInt32 numValues = 0; PRInt32 maxNumValues = child->GetMaxNumValues(); if (maxNumValues <= 0) { @@ -785,7 +783,7 @@ void nsFormFrame::ProcessAsMultipart(nsString& aData) if (child) { PRInt32 type; child->GetType(&type); - if (child->IsSuccessful()) { + if (child->IsSuccessful(aFrame)) { PRInt32 numValues = 0; PRInt32 maxNumValues = child->GetMaxNumValues(); if (maxNumValues <= 0) { diff --git a/mozilla/layout/html/forms/src/nsFormFrame.h b/mozilla/layout/html/forms/src/nsFormFrame.h index 14ef5201ea9..94fb715f29e 100644 --- a/mozilla/layout/html/forms/src/nsFormFrame.h +++ b/mozilla/layout/html/forms/src/nsFormFrame.h @@ -30,6 +30,48 @@ struct nsHTMLReflowState; class nsFormControlFrame; class nsRadioControlFrame; class nsIFormControlFrame; +class nsIDOMHTMLFormElement; + +class nsIPresContext; +class nsFormFrame; +// XXX these structs and gFormFrameTable below provide a faster way to get from a form content to +// the appropriate frame. Before replacing this mechanism with FindFrameWithContent, please test +// a page with thousands of frames and hundreds of form controls. +struct nsFormFrameTableEntry +{ + nsIPresContext* mPresContext; + nsIDOMHTMLFormElement* mFormElement; + nsFormFrame* mFormFrame; + nsFormFrameTableEntry(nsIPresContext& aPresContext, + nsIDOMHTMLFormElement& aFormElement, + nsFormFrame& aFormFrame) : mPresContext(&aPresContext), + mFormElement(&aFormElement), + mFormFrame(&aFormFrame) {} +}; +struct nsFormFrameTable +{ + nsVoidArray mEntries; + nsFormFrameTable() {} + nsFormFrame* Get(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem) { + PRInt32 count = mEntries.Count(); + for (PRInt32 i = 0; i < count; i++) { + nsFormFrameTableEntry* entry = (nsFormFrameTableEntry *)mEntries.ElementAt(i); + if ((entry->mPresContext == &aPresContext) && (entry->mFormElement == &aFormElem)) { + return entry->mFormFrame; + } + } + return nsnull; + } + void Put(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem, nsFormFrame& aFormFrame) { + mEntries.AppendElement(new nsFormFrameTableEntry(aPresContext, aFormElem, aFormFrame)); + } + ~nsFormFrameTable() { + PRInt32 count = mEntries.Count(); + for (PRInt32 i = 0; i < count; i++) { + delete mEntries.ElementAt(i); + } + } +}; class nsFormFrame : public nsLeafFrame, public nsIFormManager @@ -37,6 +79,8 @@ class nsFormFrame : public nsLeafFrame, public: nsFormFrame(nsIContent* aContent, nsIFrame* aParentFrame); + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -55,7 +99,8 @@ public: void OnRadioChecked(nsRadioControlFrame& aRadio); - void Init(nsIPresContext& aPresContext, PRBool aReinit); + void AddFormControlFrame(nsIFormControlFrame& aFrame); + static void AddFormControlFrame(nsIPresContext& aPresContext, nsIFrame& aFrame); PRBool CanSubmit(nsFormControlFrame& aFrame); @@ -64,6 +109,15 @@ public: NS_IMETHOD GetTarget(nsString* aTarget); NS_IMETHOD GetAction(nsString* aAction); + static nsFormFrame* GetFormFrame(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem) { + return gFormFrameTable->Get(aPresContext, aFormElem); + } + + static void PutFormFrame(nsIPresContext& aPresContext, nsIDOMHTMLFormElement& aFormElem, + nsFormFrame& aFrame) { + gFormFrameTable->Put(aPresContext, aFormElem, aFrame); + } + // static helper functions for nsIFormControls static PRBool GetDisabled(nsIFrame* aChildFrame, nsIContent* aContent = 0); @@ -76,8 +130,8 @@ protected: const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize); void RemoveRadioGroups(); - void ProcessAsURLEncoded(PRBool aIsPost, nsString& aData); - void ProcessAsMultipart(nsString& aData); + void ProcessAsURLEncoded(PRBool aIsPost, nsString& aData, nsIFormControlFrame* aFrame); + void ProcessAsMultipart(nsString& aData, nsIFormControlFrame* aFrame); static const char* GetFileNameWithinPath(char* aPathName); // the following are temporary until nspr and/or netlib provide them @@ -85,9 +139,10 @@ protected: static char* Temp_GenerateTempFileName(PRInt32 aMaxSize, char* aBuffer); static void Temp_GetContentType(char* aPathName, char* aContentType); + static nsFormFrameTable* gFormFrameTable; + nsVoidArray mFormControls; nsVoidArray mRadioGroups; - PRBool mInited; nsIFormControlFrame* mTextSubmitter; }; diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp index 32c0ed5a6dc..1e2e94e37eb 100644 --- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp @@ -81,7 +81,7 @@ public: NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); - virtual PRBool IsSuccessful(); + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); NS_IMETHOD GetType(PRInt32* aType) const; NS_IMETHOD GetName(nsString* aName); NS_IMETHOD GetValue(nsString* aName); @@ -281,14 +281,16 @@ nsHTMLButtonControlFrame::GetValue(nsString* aResult) } PRBool -nsHTMLButtonControlFrame::IsSuccessful() +nsHTMLButtonControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter) { - nsAutoString name; - return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); + if (this == (aSubmitter)) { + nsAutoString name; + return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name)); + } else { + return PR_FALSE; + } } - - void nsHTMLButtonControlFrame::MouseClicked(nsIPresContext* aPresContext) { @@ -525,12 +527,14 @@ nsHTMLButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, NS_IMETHODIMP nsHTMLButtonControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { + // add ourself as an nsIFormControlFrame + nsFormFrame::AddFormControlFrame(aPresContext, *this); + // create our view, we need a view to grab the mouse nsIView* view; GetView(view); if (!view) { - nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, - (void **)&view); + nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view); nsIPresShell *presShell = aPresContext.GetShell(); nsIViewManager *viewMan = presShell->GetViewManager(); NS_RELEASE(presShell); diff --git a/mozilla/layout/html/forms/src/nsIFormControlFrame.h b/mozilla/layout/html/forms/src/nsIFormControlFrame.h index af08e310ca1..f895400a020 100644 --- a/mozilla/layout/html/forms/src/nsIFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsIFormControlFrame.h @@ -48,7 +48,7 @@ public: virtual void Reset() = 0; - virtual PRBool IsSuccessful() = 0; + virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter) = 0; virtual PRInt32 GetMaxNumValues() = 0; diff --git a/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp b/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp index 57bf0a66be3..5d65a968651 100644 --- a/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsSelectControlFrame.cpp @@ -479,6 +479,7 @@ nsSelectControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, if (index >= 0) { nsAutoString value; GetOptionValue(*options, index, value); + aNumValues = 1; aNames[0] = name; aValues[0] = value; status = PR_TRUE; @@ -496,7 +497,7 @@ nsSelectControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, aNumValues = 0; for (int i = 0; i < numSelections; i++) { nsAutoString value; - GetOptionValue(*options, i, value); + GetOptionValue(*options, selections[i], value); aNames[i] = name; aValues[i] = value; aNumValues++; @@ -589,10 +590,12 @@ nsSelectControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 PRBool status = PR_FALSE; nsIDOMHTMLOptionElement* option = GetOption(aCollection, aIndex); if (option) { - if (NS_CONTENT_ATTR_HAS_VALUE == option->GetValue(aValue)) { + nsresult result = option->GetValue(aValue); + if (aValue.Length() > 0) { status = PR_TRUE; } else { - if (NS_CONTENT_ATTR_HAS_VALUE == option->GetText(aValue)) { + result = option->GetText(aValue); + if (aValue.Length() > 0) { status = PR_TRUE; } } diff --git a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp index 43eb46188ef..db0a649a714 100644 --- a/mozilla/layout/html/forms/src/nsTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsTextControlFrame.cpp @@ -114,7 +114,7 @@ nsTextControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext, if (NS_FORM_TEXTAREA == type) { padding = (nscoord)(40 * aCharWidth / 100); } else { - padding = (nscoord)(55 * aCharWidth / 100); + padding = (nscoord)(95 * aCharWidth / 100); } nscoord min = NSIntPixelsToTwips(3, aPixToTwip); if (padding > min) { @@ -191,9 +191,9 @@ nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext, if (NS_CONTENT_ATTR_HAS_VALUE != GetSize(&width)) { width = 20; } - if (eCompatibility_NavQuirks == mode) { - width += 1; - } + //if (eCompatibility_NavQuirks == mode) { + // width += 1; + //} nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull, width, PR_FALSE, nsnull, 1); CalculateSize(aPresContext, this, styleSize, textSpec, size,