From 4a95093116f5ad98a5bb23c11d49f3012c965456 Mon Sep 17 00:00:00 2001 From: karnaze Date: Fri, 24 Apr 1998 21:37:30 +0000 Subject: [PATCH] added radio groups, select/option, beter sizing. widgets take creation parms. git-svn-id: svn://10.0.0.236/trunk@616 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/base/src/nsString.cpp | 2 + .../html/document/src/nsHTMLContentSink.cpp | 6 + .../layout/html/base/src/nsAbsoluteFrame.cpp | 4 +- .../html/document/src/nsHTMLContentSink.cpp | 6 + .../layout/html/forms/public/nsIFormControl.h | 7 +- .../layout/html/forms/public/nsIFormManager.h | 20 +- mozilla/layout/html/forms/src/Makefile | 3 +- mozilla/layout/html/forms/src/makefile.win | 9 +- mozilla/layout/html/forms/src/nsForm.cpp | 154 ++++- mozilla/layout/html/forms/src/nsHTMLForms.h | 29 + mozilla/layout/html/forms/src/nsInput.cpp | 194 +++++- mozilla/layout/html/forms/src/nsInput.h | 39 +- .../layout/html/forms/src/nsInputButton.cpp | 248 ++++--- .../layout/html/forms/src/nsInputCheckbox.cpp | 62 +- .../layout/html/forms/src/nsInputCheckbox.h | 3 +- mozilla/layout/html/forms/src/nsInputFile.cpp | 58 +- mozilla/layout/html/forms/src/nsInputFile.h | 5 - .../layout/html/forms/src/nsInputFrame.cpp | 297 ++++++++- mozilla/layout/html/forms/src/nsInputFrame.h | 94 ++- .../layout/html/forms/src/nsInputHidden.cpp | 155 ----- mozilla/layout/html/forms/src/nsInputHidden.h | 52 -- .../layout/html/forms/src/nsInputImage.cpp | 22 +- mozilla/layout/html/forms/src/nsInputImage.h | 7 +- .../layout/html/forms/src/nsInputPassword.cpp | 163 ----- .../layout/html/forms/src/nsInputPassword.h | 42 -- .../layout/html/forms/src/nsInputRadio.cpp | 200 +++++- mozilla/layout/html/forms/src/nsInputRadio.h | 44 +- mozilla/layout/html/forms/src/nsInputText.cpp | 224 +++++-- mozilla/layout/html/forms/src/nsInputText.h | 23 +- mozilla/layout/html/forms/src/nsSelect.cpp | 623 ++++++++++++++++++ mozilla/string/obsolete/nsString.cpp | 2 + mozilla/view/public/nsIView.h | 3 + mozilla/view/src/nsScrollingView.cpp | 3 +- mozilla/view/src/nsScrollingView.h | 1 + mozilla/view/src/nsView.cpp | 7 +- mozilla/view/src/nsView.h | 2 + mozilla/webshell/src/nsWebWidget.cpp | 1 + .../webshell/tests/viewer/samples/test8.html | 53 +- mozilla/widget/public/nsIFileWidget.h | 4 +- mozilla/widget/public/nsIWidget.h | 8 +- mozilla/widget/src/windows/nsComboBox.cpp | 10 +- mozilla/widget/src/windows/nsFileWidget.cpp | 3 +- mozilla/widget/src/windows/nsFileWidget.h | 3 +- mozilla/widget/src/windows/nsListBox.cpp | 18 +- mozilla/widget/src/windows/nsListBox.h | 2 +- mozilla/widget/src/windows/nsRadioButton.cpp | 17 - mozilla/widget/src/windows/nsRadioButton.h | 2 - .../widget/src/windows/nsTextAreaWidget.cpp | 3 +- mozilla/widget/src/windows/nsTextHelper.cpp | 9 +- mozilla/widget/src/windows/nsTextHelper.h | 2 + mozilla/widget/src/windows/nsWindow.cpp | 28 +- mozilla/widget/src/windows/nsWindow.h | 25 +- mozilla/xpcom/ds/nsString.cpp | 2 + mozilla/xpcom/string/obsolete/nsString.cpp | 2 + 54 files changed, 2082 insertions(+), 923 deletions(-) delete mode 100644 mozilla/layout/html/forms/src/nsInputHidden.cpp delete mode 100644 mozilla/layout/html/forms/src/nsInputHidden.h delete mode 100644 mozilla/layout/html/forms/src/nsInputPassword.cpp delete mode 100644 mozilla/layout/html/forms/src/nsInputPassword.h create mode 100644 mozilla/layout/html/forms/src/nsSelect.cpp diff --git a/mozilla/base/src/nsString.cpp b/mozilla/base/src/nsString.cpp index e3dd9f715ba..a4c6b86e46a 100644 --- a/mozilla/base/src/nsString.cpp +++ b/mozilla/base/src/nsString.cpp @@ -538,6 +538,7 @@ float nsString::ToFloat(PRInt32* aErrorCode) const if (*cp != 0) { *aErrorCode = NS_ERROR_ILLEGAL_VALUE; } + *aErrorCode = NS_OK; return f; } @@ -588,6 +589,7 @@ PRInt32 nsString::ToInteger(PRInt32* aErrorCode) const { if (sign == '-') { rv = -rv; } + *aErrorCode = NS_OK; return rv; } diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index 2e398e8b19e..6050abccba9 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -1119,6 +1119,12 @@ nsresult HTMLContentSink::ProcessINPUTTag(nsIHTMLContent** aInstancePtrResult, else if (val.EqualsIgnoreCase("text")) { rv = NS_NewHTMLInputText(aInstancePtrResult, atom, mCurrentForm); } + else if (val.EqualsIgnoreCase("select1")) { // TEMP hack + rv = NS_NewHTMLSelect(aInstancePtrResult, atom, mCurrentForm, 1); + } + else if (val.EqualsIgnoreCase("select2")) { // TEMP hack + rv = NS_NewHTMLSelect(aInstancePtrResult, atom, mCurrentForm, 2); + } else { rv = NS_NewHTMLInputSubmit(aInstancePtrResult, atom, mCurrentForm); } diff --git a/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp b/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp index 793a986e69a..48f79284a7e 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp +++ b/mozilla/layout/html/base/src/nsAbsoluteFrame.cpp @@ -94,12 +94,12 @@ nsIView* AbsoluteFrame::CreateView(nsIFrame* aContainingBlock, if (NS_OK == result) { nsIView* scrolledView = scrollView->GetScrolledView(); - view->Init(viewManager, aRect, scrolledView, nsnull, nsnull, aZIndex); + view->Init(viewManager, aRect, scrolledView, nsnull, nsnull, nsnull, aZIndex); viewManager->InsertChild(scrolledView, view, 0); NS_RELEASE(scrolledView); NS_RELEASE(scrollView); } else { - view->Init(viewManager, aRect, containingView, nsnull, nsnull, aZIndex); + view->Init(viewManager, aRect, containingView, nsnull, nsnull, nsnull, aZIndex); viewManager->InsertChild(containingView, view, 0); } diff --git a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp index 2e398e8b19e..6050abccba9 100644 --- a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp @@ -1119,6 +1119,12 @@ nsresult HTMLContentSink::ProcessINPUTTag(nsIHTMLContent** aInstancePtrResult, else if (val.EqualsIgnoreCase("text")) { rv = NS_NewHTMLInputText(aInstancePtrResult, atom, mCurrentForm); } + else if (val.EqualsIgnoreCase("select1")) { // TEMP hack + rv = NS_NewHTMLSelect(aInstancePtrResult, atom, mCurrentForm, 1); + } + else if (val.EqualsIgnoreCase("select2")) { // TEMP hack + rv = NS_NewHTMLSelect(aInstancePtrResult, atom, mCurrentForm, 2); + } else { rv = NS_NewHTMLInputSubmit(aInstancePtrResult, atom, mCurrentForm); } diff --git a/mozilla/layout/html/forms/public/nsIFormControl.h b/mozilla/layout/html/forms/public/nsIFormControl.h index df4108eb1d6..173aa9c7280 100644 --- a/mozilla/layout/html/forms/public/nsIFormControl.h +++ b/mozilla/layout/html/forms/public/nsIFormControl.h @@ -31,6 +31,11 @@ class nsIFormManager; **/ class nsIFormControl : public nsISupports { public: + + virtual void GetType(nsString& aType) const = 0; + virtual PRBool GetChecked(PRBool aGetInitialValue) const = 0; + virtual void SetChecked(PRBool aState, PRBool aSetInitialValue) = 0; + /** * Get the form manager which manages this control. * @return the form manager @@ -50,7 +55,7 @@ public: * @param aResult the nsString which will be set to the name (out parm) * @return PR_TRUE if there was a name, PR_FALSE otherwise */ - virtual PRBool GetName(nsString& aResult) = 0; + virtual PRBool GetName(nsString& aResult) const = 0; /** * Get the number of references to this control by other objects. diff --git a/mozilla/layout/html/forms/public/nsIFormManager.h b/mozilla/layout/html/forms/public/nsIFormManager.h index e60944a32f8..770dd5c43dc 100644 --- a/mozilla/layout/html/forms/public/nsIFormManager.h +++ b/mozilla/layout/html/forms/public/nsIFormManager.h @@ -20,6 +20,8 @@ #include "nsISupports.h" class nsIFormControl; +class nsIPresContext; +class nsIFrame; // IID for the nsIFormManager interface #define NS_IFORMMANAGER_IID \ @@ -36,6 +38,13 @@ class nsIFormManager : public nsISupports { public: // Event methods + /** + * Respond to a radio button being checked. This form manager is responsible + * for radio group coordination. + * @param aRadio the radio button that was checked + */ + virtual void OnRadioChecked(nsIFormControl& aRadio) = 0; + /** * Reset the values of all of this manager's controls back to their * initial values. This is in response to a reset button being pushed. @@ -52,8 +61,10 @@ public: /** * Submit the values of this manager's controls depending on its action, * method attributes. This in response to a submit button being clicked. + * @param aPresContext the presentation context + * @param aFrame the frame of the submit button */ - virtual void OnSubmit() = 0; + virtual void OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame) = 0; /** * This is tbd and is in repsonse to a tab key being entered in one @@ -112,6 +123,13 @@ public: // misc methods + /** + * Initialize this form manager after all of the controls have been added + * This makes it possible to determine what the radio groups are. + * @param aReinit if PR_TRUE initialize even if Init has been called before. + */ + virtual void Init(PRBool aReinit) = 0; + /** * Get the number of references to this form manager by other objects. * @return the ref count diff --git a/mozilla/layout/html/forms/src/Makefile b/mozilla/layout/html/forms/src/Makefile index b7cbd522eeb..a4d1cec88f4 100644 --- a/mozilla/layout/html/forms/src/Makefile +++ b/mozilla/layout/html/forms/src/Makefile @@ -31,11 +31,10 @@ CPPSRCS = \ nsInputCheckbox.cpp \ nsInputFile.cpp \ nsInputFrame.cpp \ - nsInputHidden.cpp \ nsInputImage.cpp \ - nsInputPassword.cpp \ nsInputRadio.cpp \ nsInputText.cpp \ + nsSelect.cpp \ $(NULL) MODULE = raptor diff --git a/mozilla/layout/html/forms/src/makefile.win b/mozilla/layout/html/forms/src/makefile.win index 853469b3939..21265e6fbf4 100644 --- a/mozilla/layout/html/forms/src/makefile.win +++ b/mozilla/layout/html/forms/src/makefile.win @@ -25,15 +25,14 @@ MODULE=raptor REQUIRES=xpcom raptor CPPSRCS=nsForm.cpp nsInput.cpp nsInputButton.cpp nsInputCheckbox.cpp \ - nsInputFile.cpp nsInputFrame.cpp nsInputHidden.cpp nsInputImage.cpp \ - nsInputPassword.cpp nsInputRadio.cpp nsInputText.cpp + nsInputFile.cpp nsInputFrame.cpp nsInputImage.cpp \ + nsInputRadio.cpp nsInputText.cpp nsSelect.cpp CPP_OBJS=.\$(OBJDIR)\nsForm.obj .\$(OBJDIR)\nsInput.obj \ .\$(OBJDIR)\nsInputButton.obj .\$(OBJDIR)\nsInputCheckbox.obj \ .\$(OBJDIR)\nsInputFile.obj .\$(OBJDIR)\nsInputFrame.obj \ - .\$(OBJDIR)\nsInputHidden.obj .\$(OBJDIR)\nsInputImage.obj \ - .\$(OBJDIR)\nsInputPassword.obj .\$(OBJDIR)\nsInputRadio.obj \ - .\$(OBJDIR)\nsInputText.obj + .\$(OBJDIR)\nsInputImage.obj .\$(OBJDIR)\nsInputRadio.obj \ + .\$(OBJDIR)\nsInputText.obj .\$(OBJDIR)\nsSelect.obj LINCS=-I$(XPDIST)\public\xpcom -I$(XPDIST)\public\raptor \ -I..\..\base\src -I..\..\style\src \ diff --git a/mozilla/layout/html/forms/src/nsForm.cpp b/mozilla/layout/html/forms/src/nsForm.cpp index ef82b8db1cd..583a7489e17 100644 --- a/mozilla/layout/html/forms/src/nsForm.cpp +++ b/mozilla/layout/html/forms/src/nsForm.cpp @@ -33,6 +33,11 @@ #include "nsHTMLAtoms.h" #include "nsIHTMLAttributes.h" #include "nsCRT.h" +#include "nsIURL.h" +#include "nsIDocument.h" +#include "nsILinkHandler.h" +#include "nsInputRadio.h" +#include "nsIRadioButton.h" // netlib has a general function (netlib\modules\liburl\src\escape.c) // which does url encoding. Since netlib is not yet available for raptor, @@ -85,7 +90,7 @@ public: // Construct a new Form Element with no attributes. This needs to be // made private and have a static COM create method. nsForm(nsIAtom* aTag); - ~nsForm(); + virtual ~nsForm(); void* operator new(size_t sz) { void* rv = new char[sz]; @@ -93,8 +98,10 @@ public: return rv; } - NS_DECL_ISUPPORTS + NS_DECL_ISUPPORTS; + virtual void OnRadioChecked(nsIFormControl& aRadio); + // callback for reset button controls. virtual void OnReset(); @@ -104,7 +111,7 @@ public: virtual void OnReturn(); // callback for submit button controls. - virtual void OnSubmit(); + virtual void OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame); // callback for tabs on controls that can gain focus. This will // eventually need to be handled at the document level to support @@ -124,14 +131,20 @@ public: virtual nsresult GetRefCount() const; + virtual void Init(PRBool aReinit); + protected: + void RemoveRadioGroups(); + nsIAtom* mTag; nsIHTMLAttributes* mAttributes; nsVoidArray mChildren; + nsVoidArray mRadioGroups; nsString* mAction; nsString* mEncoding; nsString* mTarget; PRInt32 mMethod; + PRBool mInited; }; #define METHOD_UNSET 0 @@ -146,6 +159,7 @@ nsForm::nsForm(nsIAtom* aTag) NS_INIT_REFCNT(); mTag = aTag; NS_IF_ADDREF(aTag); + mInited = PR_FALSE; } nsForm::~nsForm() @@ -161,6 +175,8 @@ nsForm::~nsForm() if (nsnull != mAction) delete mAction; if (nsnull != mEncoding) delete mEncoding; if (nsnull != mTarget) delete mTarget; + + RemoveRadioGroups(); } NS_IMPL_QUERY_INTERFACE(nsForm,kIFormManagerIID); @@ -175,7 +191,7 @@ nsrefcnt nsForm::Release() { --mRefCnt; int numChildren = GetFormControlCount(); - PRBool externalRefsToChildren = PR_FALSE; // are there refs to any children besides me + PRBool externalRefsToChildren = PR_FALSE; // are there refs to any children besides my ref for (int i = 0; i < numChildren; i++) { nsIFormControl* child = GetFormControlAt(i); if (child->GetRefCount() > 1) { @@ -241,12 +257,21 @@ nsForm::OnReturn() } void -nsForm::OnSubmit() +nsForm::OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame) { - nsString data(""); // this could be more efficient, by allocating a larger buffer + printf("\n YYYYYYYYYYYYY \n"); + // right now we only do "get" + nsAutoString method, href; + GetAttribute("method", method); + PRBool isPost = (method.EqualsIgnoreCase("post")) ? PR_TRUE : PR_FALSE; + GetAttribute("action", href); + + nsString data(href); // this could be more efficient, by allocating a larger buffer + data += '$'; PRBool firstTime = PR_TRUE; PRInt32 numChildren = mChildren.Count(); + // collect and encode the data from the children controls for (PRInt32 childX = 0; childX < numChildren; childX++) { nsIFormControl* child = (nsIFormControl*) mChildren.ElementAt(childX); nsString childName; @@ -276,9 +301,39 @@ nsForm::OnSubmit() delete [] values; } } + char* out = data.ToNewCString(); printf("\nsubmit data =\n%s\n", out); delete [] out; + +#ifdef FIX_THIS + // cause the url + nsILinkHandler* handler; + if (NS_OK == aPresContext->GetLinkHandler(&handler)) { + // Resolve url to an absolute url + nsIURL* docURL = nsnull; + nsIContent* content; + aFrame->GetContent(content); + if (nsnull != content) { + nsIDocument* doc = content->GetDocument(); + docURL = doc->GetDocumentURL(); + NS_RELEASE(doc); + NS_RELEASE(content); + } + + nsAutoString target, method; + GetAttribute("target", target); + + nsAutoString absURLSpec; + nsAutoString base; + nsresult rv = NS_MakeAbsoluteURL(docURL, base, href, absURLSpec); + NS_IF_RELEASE(docURL); + + // Now pass on absolute url to the click handler + handler->OnLinkClick(aFrame, absURLSpec, target); + } +#endif + } void @@ -290,7 +345,7 @@ void nsForm::SetAttribute(const nsString& aName, const nsString& aValue) { nsAutoString tmp(aName); tmp.ToUpperCase(); - nsIAtom* atom = NS_NewAtom(aName); + nsIAtom* atom = NS_NewAtom(tmp); if (atom == nsHTMLAtoms::action) { nsAutoString url(aValue); @@ -343,7 +398,7 @@ PRBool nsForm::GetAttribute(const nsString& aName, { nsAutoString tmp(aName); tmp.ToUpperCase(); - nsIAtom* atom = NS_NewAtom(aName); + nsIAtom* atom = NS_NewAtom(tmp); PRBool rv = PR_FALSE; if (atom == nsHTMLAtoms::action) { if (nsnull != mAction) { @@ -391,6 +446,88 @@ PRBool nsForm::GetAttribute(const nsString& aName, return rv; } +void nsForm::RemoveRadioGroups() +{ + int numRadioGroups = mRadioGroups.Count(); + for (int i = 0; i < numRadioGroups; i++) { + nsInputRadioGroup* radioGroup = (nsInputRadioGroup *) mRadioGroups.ElementAt(i); + delete radioGroup; + mRadioGroups.RemoveElement(radioGroup); + } +} + +void nsForm::Init(PRBool aReinit) +{ + if (mInited && !aReinit) { + return; + } + mInited = PR_TRUE; + 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 + 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))) { + int numGroups = mRadioGroups.Count(); + PRBool added = PR_FALSE; + nsInputRadioGroup* group; + for (int j = 0; j < numGroups; j++) { + group = (nsInputRadioGroup *) mRadioGroups.ElementAt(j); + nsString name; + group->GetName(name); + if (name.Equals(name)) { + group->AddRadio(control); + added = PR_TRUE; + break; + } + } + if (!added) { + group = new nsInputRadioGroup(name); + mRadioGroups.AppendElement(group); + group->AddRadio(control); + } + // allow only one checked radio button + if (control->GetChecked(PR_TRUE)) { + if (nsnull == group->GetCheckedRadio()) { + group->SetCheckedRadio(control); + } + else { + control->SetChecked(PR_FALSE, PR_TRUE); + } + } + } + } +} + +void +nsForm::OnRadioChecked(nsIFormControl& aControl) +{ + nsString radioName; + if (!aControl.GetName(radioName)) { // don't consider a radio without a name + return; + } + + // locate the radio group with the name of aRadio + int numGroups = mRadioGroups.Count(); + for (int j = 0; j < numGroups; j++) { + nsInputRadioGroup* group = (nsInputRadioGroup *) mRadioGroups.ElementAt(j); + nsString groupName; + group->GetName(groupName); + nsIFormControl* checkedRadio = group->GetCheckedRadio(); + printf("\n group name=%s radio name=%s", groupName.ToNewCString(), radioName.ToNewCString()); + if (groupName.Equals(radioName) && (nsnull != checkedRadio) & (&aControl != checkedRadio)) { + checkedRadio->SetChecked(PR_FALSE, PR_FALSE); + group->SetCheckedRadio(&aControl); + } + } +} + nsresult NS_NewHTMLForm(nsIFormManager** aInstancePtrResult, nsIAtom* aTag) @@ -408,3 +545,4 @@ NS_NewHTMLForm(nsIFormManager** aInstancePtrResult, nsresult result = it->QueryInterface(kIFormManagerIID, (void**) aInstancePtrResult); return result; } + diff --git a/mozilla/layout/html/forms/src/nsHTMLForms.h b/mozilla/layout/html/forms/src/nsHTMLForms.h index b755b90cf6e..10ae6cac51d 100644 --- a/mozilla/layout/html/forms/src/nsHTMLForms.h +++ b/mozilla/layout/html/forms/src/nsHTMLForms.h @@ -22,6 +22,10 @@ class nsIAtom; class nsIFormManager; +// fix these +#define CSS_NOTSET 0 +#define ATTR_NOTSET 0 + // Form and Form Controls /** @@ -95,6 +99,15 @@ extern nsresult NS_NewHTMLInputImage(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager); +/** + * Construct an nsIHTMLContent with behavior of an html select + * @see NS_NewHTMLInputButton for parameter and return values + */ +extern nsresult +NS_NewHTMLOption(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag); + + /** * Construct an nsIHTMLContent with behavior of an html input password * @see NS_NewHTMLInputButton for parameter and return values @@ -111,6 +124,14 @@ extern nsresult NS_NewHTMLInputRadio(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager); +/** + * Construct an nsIHTMLContent with behavior of an html select + * @see NS_NewHTMLInputButton for parameter and return values + */ +extern nsresult +NS_NewHTMLSelect(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aManager, PRInt32 aHackIndex); + /** * Construct an nsIHTMLContent with behavior of an html input text * @see NS_NewHTMLInputButton for parameter and return values @@ -119,4 +140,12 @@ extern nsresult NS_NewHTMLInputText(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager); +/** + * Construct an nsIHTMLContent with behavior of an html text area + * @see NS_NewHTMLInputButton for parameter and return values + */ +extern nsresult +NS_NewHTMLTextArea(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aManager); + #endif /* nsHTMLForms_h___ */ diff --git a/mozilla/layout/html/forms/src/nsInput.cpp b/mozilla/layout/html/forms/src/nsInput.cpp index 719ccab225a..a5e7661d1d7 100644 --- a/mozilla/layout/html/forms/src/nsInput.cpp +++ b/mozilla/layout/html/forms/src/nsInput.cpp @@ -19,7 +19,7 @@ #include "nsIFormManager.h" #include "nsInputFrame.h" #include "nsHTMLParts.h" -#include "nsHTMLTagContent.h" +#include "nsHTMLContainer.h" #include "nsIRenderingContext.h" #include "nsIPresShell.h" #include "nsIPresContext.h" @@ -30,29 +30,32 @@ #include "nsHTMLAtoms.h" #include "nsIView.h" #include "nsIViewManager.h" -#include "nsCoord.h" +#include "nscoord.h" #include "nsDebug.h" #include "nsIWidget.h" +#include "nsHTMLForms.h" // Note: we inherit a base class operator new that zeros our memory nsInput::nsInput(nsIAtom* aTag, nsIFormManager* aManager) - : nsHTMLTagContent(aTag), mControl() + : nsHTMLContainer(aTag), mControl() { -printf("** nsInput::nsInput this=%d\n", this); mFormMan = aManager; if (nsnull != mFormMan) { NS_ADDREF(mFormMan); mFormMan->AddFormControl(&mControl); } + mSize = CSS_NOTSET; // not set } nsInput::~nsInput() { -printf("** nsInput::~nsInput()\n"); NS_IF_RELEASE(mWidget); if (nsnull != mName) { delete mName; } + if (nsnull != mValue) { + delete mName; + } if (nsnull != mFormMan) { // prevent mFormMan from decrementing its ref count on us mFormMan->RemoveFormControl(&mControl, PR_FALSE); @@ -69,7 +72,7 @@ nsresult nsInput::QueryInterface(REFNSIID aIID, void** aInstancePtr) *aInstancePtr = (void**) &mControl; return NS_OK; } - return nsHTMLTagContent::QueryInterface(aIID, aInstancePtr); + return nsHTMLContainer::QueryInterface(aIID, aInstancePtr); } nsrefcnt nsInput::Release() @@ -117,6 +120,12 @@ nsInput::CreateFrame(nsIPresContext *aPresContext, return nsnull; } +PRBool +nsInput::IsHidden() +{ + return PR_FALSE; +} + void nsInput::SetWidget(nsIWidget* aWidget) { @@ -161,7 +170,7 @@ nsInput::GetFormManager() const * then return PR_FALSE (form elements without names are not submitable). */ PRBool -nsInput::GetName(nsString& aName) +nsInput::GetName(nsString& aName) const { if ((nsnull != mName) && (0 != mName->Length())) { aName = *mName; @@ -188,45 +197,158 @@ nsInput::GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues return PR_FALSE; } +void nsInput::CacheAttribute(const nsString& aValue, nsString*& aLoc) +{ + if (nsnull == aLoc) { + aLoc = new nsString(aValue); + } else { + aLoc->SetLength(0); + aLoc->Append(aValue); + } +} + +void nsInput::CacheAttribute(const nsString& aValue, PRInt32 aMinValue, PRInt32& aLoc) +{ + PRInt32 status; + PRInt32 intVal = aValue.ToInteger(&status); + aLoc = ((NS_OK == status) && (intVal >= aMinValue)) ? intVal : aMinValue; +} + void nsInput::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) { - if (aAttribute == nsHTMLAtoms::type) { - // You cannot set the type of a form element + if (aAttribute == nsHTMLAtoms::type) { // You cannot set the type of a form element return; - } + } else if (aAttribute == nsHTMLAtoms::name) { - if (nsnull == mName) { - mName = new nsString(aValue); - } else { - mName->SetLength(0); - mName->Append(aValue); - } + CacheAttribute(aValue, mName); + } + else if (aAttribute == nsHTMLAtoms::size) { + CacheAttribute(aValue, CSS_NOTSET, mSize); + } + else if (aAttribute == nsHTMLAtoms::value) { + CacheAttribute(aValue, mValue); + } + else { + nsHTMLContainer::SetAttribute(aAttribute, aValue); // YYY remove this + } +} + +nsContentAttr nsInput::GetCacheAttribute(nsString* const& aLoc, nsHTMLValue& aValue) const +{ + aValue.Reset(); + if (nsnull == aLoc) { + return eContentAttr_NotThere; + } + else { + aValue.Set(*aLoc); + return eContentAttr_HasValue; + } +} + +nsContentAttr nsInput::GetCacheAttribute(PRInt32 aLoc, nsHTMLValue& aValue) const +{ + aValue.Reset(); + if (aLoc <= CSS_NOTSET) { + return eContentAttr_NotThere; + } + else { + aValue.Set(aLoc); + return eContentAttr_HasValue; + } +} + +nsContentAttr nsInput::GetCacheAttribute(PRBool aLoc, nsHTMLValue& aValue) const +{ + aValue.Reset(); + if (aLoc) { + aValue.Set(1); + return eContentAttr_HasValue; + } + else { + return eContentAttr_NotThere; + } +} + +nsContentAttr nsInput::GetAttribute(nsIAtom* aAttribute, nsString& aValue) const +{ + nsHTMLValue htmlValue; + nsContentAttr result = GetAttribute(aAttribute, htmlValue); + if (eContentAttr_HasValue == result) { + htmlValue.GetStringValue(aValue); + return eContentAttr_HasValue; + } + else { + aValue = ""; + return eContentAttr_NoValue; + } +} + +nsContentAttr nsInput::GetAttribute(nsIAtom* aAttribute, PRInt32& aValue) const +{ + nsHTMLValue htmlValue; + nsContentAttr result = GetAttribute(aAttribute, htmlValue); + if (eContentAttr_HasValue == result) { + aValue = htmlValue.GetIntValue(); + return eContentAttr_HasValue; + } + else { + aValue = ATTR_NOTSET; + return eContentAttr_NoValue; + } +} + +nsContentAttr nsInput::GetAttribute(nsIAtom* aAttribute, PRBool& aValue) const +{ + PRInt32 intVal; + nsContentAttr result = GetAttribute(aAttribute, intVal); + if ((eContentAttr_HasValue == result) && (intVal > 0)) { + aValue = PR_TRUE; + return eContentAttr_HasValue; + } + else { + aValue = PR_FALSE; + return eContentAttr_NoValue; } } nsContentAttr nsInput::GetAttribute(nsIAtom* aAttribute, nsHTMLValue& aValue) const { - nsContentAttr ca = eContentAttr_NotThere; if (aAttribute == nsHTMLAtoms::type) { nsAutoString tmp; GetType(tmp); - aValue.Set(tmp); - ca = eContentAttr_HasValue; - } - else if (aAttribute == nsHTMLAtoms::name) { - aValue.Reset(); - if (nsnull != mName) { - aValue.Set(*mName); - ca = eContentAttr_HasValue; + if (tmp.Length() == 0) { // derivatives that don't support type return zero length string + return eContentAttr_NotThere; } + else { + aValue.Set(tmp); + return eContentAttr_HasValue; + } + } + else if (aAttribute == nsHTMLAtoms::name) { + return GetCacheAttribute(mName, aValue); + } + else if (aAttribute == nsHTMLAtoms::size) { + return GetCacheAttribute(mSize, aValue); + } + else if (aAttribute == nsHTMLAtoms::value) { + return GetCacheAttribute(mValue, aValue); } else { - ca = nsHTMLTagContent::GetAttribute(aAttribute, aValue); + return eContentAttr_NotThere; } - return ca; } +PRBool nsInput::GetChecked(PRBool aGetInitialValue) const +{ + return PR_FALSE; +} + +void nsInput::SetChecked(PRBool aState, PRBool aSetInitialValue) +{ +} + + //---------------------------------------------------------------------- #define GET_OUTER() ((nsInput*) ((char*)this - nsInput::GetOuterOffset())) @@ -254,7 +376,7 @@ nsresult nsInput::AggInputControl::QueryInterface(REFNSIID aIID, void** aInstanc return GET_OUTER()->QueryInterface(aIID, aInstancePtr); } -PRBool nsInput::AggInputControl::GetName(nsString& aName) +PRBool nsInput::AggInputControl::GetName(nsString& aName) const { return GET_OUTER()->GetName(aName); } @@ -290,3 +412,19 @@ nsrefcnt nsInput::AggInputControl::GetRefCount() const { return GET_OUTER()->GetRefCount(); } + +PRBool nsInput::AggInputControl::GetChecked(PRBool aGetInitialValue) const +{ + return GET_OUTER()->GetChecked(aGetInitialValue); +} + +void nsInput::AggInputControl::SetChecked(PRBool aState, PRBool aSetInitialValue) +{ + GET_OUTER()->SetChecked(aState, aSetInitialValue); +} + +void nsInput::AggInputControl::GetType(nsString& aName) const +{ + GET_OUTER()->GetType(aName); +} + diff --git a/mozilla/layout/html/forms/src/nsInput.h b/mozilla/layout/html/forms/src/nsInput.h index 1ab6777fe99..fde4e8c232e 100644 --- a/mozilla/layout/html/forms/src/nsInput.h +++ b/mozilla/layout/html/forms/src/nsInput.h @@ -19,19 +19,19 @@ #ifndef nsInput_h___ #define nsInput_h___ -#include "nsHTMLTagContent.h" +#include "nsHTMLContainer.h" #include "nsIFormControl.h" class nsIFormManager; class nsIWidget; class nsIView; -class nsString; +class nsIPresContext; /** * nsInput represents an html Input element. This is a base class for * the various Input types (button, checkbox, file, hidden, password, * reset, radio, submit, text) */ -class nsInput : public nsHTMLTagContent { +class nsInput : public nsHTMLContainer { public: /** * main constructor @@ -72,7 +72,7 @@ public: /** * @see nsIFormControl GetFormManager */ - virtual PRBool GetName(nsString& aName); + virtual PRBool GetName(nsString& aName) const; /** * @see nsIFormControl GetFormManager @@ -80,6 +80,8 @@ public: virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues); + virtual PRBool IsHidden(); + /** * @see nsIFormControl GetFormManager */ @@ -103,6 +105,10 @@ public: virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, nsHTMLValue& aValue) const; + virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, nsString& aValue) const; + virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, PRInt32& aValue) const; + virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, PRBool& aValue) const; + /** * Set the named attribute of this input * @param aAttribute the name of the attribute @@ -136,19 +142,29 @@ public: return offsetof(nsInput,mControl); } + virtual void GetType(nsString& aResult) const = 0; + virtual PRBool GetChecked(PRBool aGetInitialValue) const; + virtual void SetChecked(PRBool aState, PRBool aSetInitialValue); + protected: virtual ~nsInput(); - /* - * Get the type of this input object - */ - virtual void GetType(nsString& aResult) const = 0; - + /** + * Get the type of this control + */ nsIWidget* mWidget; nsIFormManager* mFormMan; + void CacheAttribute(const nsString& aValue, nsString*& aLoc); + void CacheAttribute(const nsString& aValue, PRInt32 aMinValue, PRInt32& aLoc); + nsContentAttr GetCacheAttribute(nsString* const& aLoc, nsHTMLValue& aValue) const; + nsContentAttr GetCacheAttribute(PRInt32 aLoc, nsHTMLValue& aValue) const; + nsContentAttr GetCacheAttribute(PRBool aLoc, nsHTMLValue& aValue) const; + // Attributes common to all html form elements nsString* mName; + nsString* mValue; + PRInt32 mSize; // Aggregator class and instance variable used to aggregate in the // nsIFormControl interface to nsInput w/o using multiple @@ -162,7 +178,8 @@ protected: NS_DECL_ISUPPORTS // nsIFormControl - virtual PRBool GetName(nsString& aName); + virtual PRBool GetName(nsString& aName) const; + virtual void GetType(nsString& aType) const; virtual PRInt32 GetMaxNumValues(); virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues); @@ -170,6 +187,8 @@ protected: virtual void SetFormManager(nsIFormManager* aFormMan, PRBool aDecrementRef = PR_TRUE); virtual nsIFormManager* GetFormManager() const; virtual nsrefcnt GetRefCount() const; + virtual PRBool GetChecked(PRBool aGetInitialValue) const; + virtual void SetChecked(PRBool aState, PRBool aSetInitialValue); }; AggInputControl mControl; }; diff --git a/mozilla/layout/html/forms/src/nsInputButton.cpp b/mozilla/layout/html/forms/src/nsInputButton.cpp index 74cbbd6015c..fd99b91a33b 100644 --- a/mozilla/layout/html/forms/src/nsInputButton.cpp +++ b/mozilla/layout/html/forms/src/nsInputButton.cpp @@ -19,7 +19,7 @@ #include "nsInput.h" #include "nsInputFrame.h" #include "nsHTMLParts.h" -#include "nsHTMLTagContent.h" +#include "nsHTMLContainer.h" #include "nsIRenderingContext.h" #include "nsIPresContext.h" #include "nsIPresShell.h" @@ -40,12 +40,12 @@ #include "nsIFontMetrics.h" #include "nsIFormManager.h" -static NS_DEFINE_IID(kStyleFontSID, NS_STYLEFONT_SID); - enum nsInputButtonType { - kInputButtonButton, - kInputButtonReset, - kInputButtonSubmit + kButton_InputButton, + kButton_Button, + kButton_InputReset, + kButton_InputSubmit, + kButton_InputHidden }; class nsInputButton : public nsInput { @@ -57,11 +57,6 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); - - virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const; - virtual void GetDefaultLabel(nsString& aLabel); nsInputButtonType GetButtonType() { return mType; } @@ -70,10 +65,7 @@ public: virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues); - // Attributes - nsString* mValue; - nscoord mWidth; - nscoord mHeight; + virtual PRBool IsHidden(); protected: virtual ~nsInputButton(); @@ -89,22 +81,24 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView* aView); - virtual void InitializeWidget(nsIView* aView); - - virtual void MouseClicked(); + virtual void MouseClicked(nsIPresContext* aPresContext); virtual const nsIID GetCID(); virtual const nsIID GetIID(); + nsInputButtonType GetButtonType() const; + protected: - virtual ~nsInputButtonFrame(); - nsString mCacheLabel; - nsFont* mCacheFont; // XXX this is bad, the lifetime of the font is not known or controlled + virtual ~nsInputButtonFrame(); + + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize); }; @@ -114,8 +108,6 @@ nsInputButton::nsInputButton(nsIAtom* aTag, nsIFormManager* aManager, nsInputButtonType aType) : nsInput(aTag, aManager), mType(aType) { - mWidth = -1; - mHeight = -1; } nsInputButton::~nsInputButton() @@ -125,73 +117,30 @@ nsInputButton::~nsInputButton() } } - -void nsInputButton::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) +PRBool +nsInputButton::IsHidden() { - if (aAttribute == nsHTMLAtoms::value) { - if (nsnull == mValue) { - mValue = new nsString(aValue); - } else { - mValue->SetLength(0); - mValue->Append(aValue); - } - } - else if (aAttribute == nsHTMLAtoms::width) { - nsHTMLValue value; - ParseValue(aValue, 0, 1000, value); - mWidth = value.GetIntValue(); - } - else if (aAttribute == nsHTMLAtoms::height) { - nsHTMLValue value; - ParseValue(aValue, 0, 1000, value); - mHeight = value.GetIntValue(); + if (kButton_InputHidden == mType) { + return PR_TRUE; } else { - nsInput::SetAttribute(aAttribute, aValue); + return PR_FALSE; } } -nsContentAttr nsInputButton::GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const -{ - nsContentAttr ca = eContentAttr_NotThere; - aResult.Reset(); - if (aAttribute == nsHTMLAtoms::value) { - if (nsnull != mValue) { - aResult.Set(*mValue); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::width) { - if (0 <= mWidth) { - aResult.Set(mWidth, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::height) { - if (0 <= mHeight) { - aResult.Set(mHeight, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else { - ca = nsInput::GetAttribute(aAttribute, aResult); - } - return ca; -} - void nsInputButton::GetType(nsString& aResult) const { aResult.SetLength(0); switch (mType) { - case kInputButtonButton: + case kButton_InputButton: + case kButton_Button: aResult.Append("button"); break; - case kInputButtonReset: + case kButton_InputReset: aResult.Append("reset"); break; default: - case kInputButtonSubmit: + case kButton_InputSubmit: aResult.Append("submit"); break; } @@ -200,9 +149,9 @@ void nsInputButton::GetType(nsString& aResult) const void nsInputButton::GetDefaultLabel(nsString& aString) { - if (kInputButtonReset == mType) { + if (kButton_InputReset == mType) { aString = "Reset"; - } else if (kInputButtonSubmit == mType) { + } else if (kButton_InputSubmit == mType) { aString = "Submit"; } else { aString = "noname"; @@ -214,17 +163,24 @@ nsInputButton::CreateFrame(nsIPresContext* aPresContext, PRInt32 aIndexInParent, nsIFrame* aParentFrame) { - nsIFrame* rv = new nsInputButtonFrame(this, aIndexInParent, aParentFrame); - return rv; + if (kButton_InputHidden == mType) { + nsIFrame* frame; + nsFrame::NewFrame(&frame, this, aIndexInParent, aParentFrame); + return frame; + } + else { + return new nsInputButtonFrame(this, aIndexInParent, aParentFrame); + } + } PRInt32 nsInputButton::GetMaxNumValues() { - if (kInputButtonSubmit == mType) { + if ((kButton_InputSubmit == mType) || (kButton_InputHidden)) { return 1; } else { - return 0; + return 0; } } @@ -237,7 +193,7 @@ nsInputButton::GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, return PR_FALSE; } - if (kInputButtonSubmit != mType) { + if ((kButton_InputSubmit != mType) && (kButton_InputHidden != mType)) { aNumValues = 0; return PR_FALSE; } @@ -261,78 +217,98 @@ nsInputButtonFrame::nsInputButtonFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsInputFrame(aContent, aIndexInParent, aParentFrame) { - mCacheLabel = ""; - mCacheFont = nsnull; } nsInputButtonFrame::~nsInputButtonFrame() { - mCacheLabel = ""; - mCacheFont = nsnull; // should this be released? NO +} + +nsInputButtonType +nsInputButtonFrame::GetButtonType() const +{ + nsInputButton* button = (nsInputButton *)mContent; + return button->GetButtonType(); } void -nsInputButtonFrame::MouseClicked() +nsInputButtonFrame::MouseClicked(nsIPresContext* aPresContext) { nsInputButton* button = (nsInputButton *)mContent; nsIFormManager* formMan = button->GetFormManager(); if (nsnull != formMan) { - if (kInputButtonReset == button->GetButtonType()) { + if (kButton_InputReset == button->GetButtonType()) { formMan->OnReset(); - } else if (kInputButtonSubmit == button->GetButtonType()) { - formMan->OnSubmit(); + } else if (kButton_InputSubmit == button->GetButtonType()) { + //NS_ADDREF(this); + formMan->OnSubmit(aPresContext, this); + //NS_RELEASE(this); } NS_RELEASE(formMan); } } - void -nsInputButtonFrame::PreInitializeWidget(nsIPresContext* aPresContext, nsSize& aBounds) +nsInputButtonFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize) { - float p2t = aPresContext->GetPixelsToTwips(); - - nsInputButton* content = (nsInputButton *)mContent; // this must be an nsInputButton - // should this be the parent - nsStyleFont* styleFont = (nsStyleFont*)mStyleContext->GetData(kStyleFontSID); - nsIDeviceContext* deviceContext = aPresContext->GetDeviceContext(); - nsIFontCache* fontCache = deviceContext->GetFontCache(); - - // get the label for the button - nsAutoString label; - if (nsnull == content->mValue) { - content->GetDefaultLabel(label); - } else { - label.Append(*content->mValue); + if (kButton_InputHidden == GetButtonType()) { + aDesiredLayoutSize.width = 0; + aDesiredLayoutSize.height = 0; + aDesiredWidgetSize.width = 0; + aDesiredWidgetSize.height = 0; + return; } - mCacheLabel = label; // cache the label + nsSize styleSize; + GetStyleSize(*aPresContext, aMaxSize, styleSize); - // get the width and height based on the label, font, padding - nsIFontMetrics* fontMet = fontCache->GetMetricsFor(styleFont->mFont); - nscoord horPadding = (int) (5.0 * p2t); // need to get this from the widget - nscoord verPadding = (int) (5.0 * p2t); // need to get this from the widget - aBounds.width = fontMet->GetWidth(label) + (2 * horPadding); - aBounds.height = fontMet->GetHeight() + (2 * verPadding); - - mCacheFont = &(styleFont->mFont); // cache the font XXX this is bad, the lifetime of the font is not known or controlled + nsSize size; + PRBool widthExplicit, heightExplicit; + PRInt32 ignore; + nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value, 1, + PR_FALSE, nsnull, 1); + CalculateSize(aPresContext, this, styleSize, spec, size, + widthExplicit, heightExplicit, ignore); - NS_RELEASE(fontMet); - NS_RELEASE(fontCache); - NS_RELEASE(deviceContext); + if (!widthExplicit) { + size.width += 100; + } + if (!heightExplicit) { + size.height += 100; + } + + aDesiredLayoutSize.width = size.width; + aDesiredLayoutSize.height= size.height; + aDesiredWidgetSize.width = size.width; + aDesiredWidgetSize.height= size.height; } void -nsInputButtonFrame::InitializeWidget(nsIView *aView) +nsInputButtonFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { nsIButton* button; if (NS_OK == GetWidget(aView, (nsIWidget **)&button)) { - if (nsnull != mCacheFont) { - button->SetFont(*mCacheFont); - } - button->SetLabel(mCacheLabel); - NS_RELEASE(button); + button->SetFont(GetFont(aPresContext)); + } + else { + NS_ASSERTION(0, "no widget in button control"); } + + nsInputButton* content; + GetContent((nsIContent*&) content); + nsString value; + nsContentAttr status = content->GetAttribute(nsHTMLAtoms::value, value); + if (eContentAttr_HasValue == status) { + button->SetLabel(value); + } + else { + button->SetLabel(" "); + } + + NS_RELEASE(content); + NS_RELEASE(button); } const nsIID @@ -371,19 +347,33 @@ nsresult NS_NewHTMLInputButton(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { - return CreateButton(aInstancePtrResult, aTag, aManager, kInputButtonButton); + return CreateButton(aInstancePtrResult, aTag, aManager, kButton_InputButton); +} + +nsresult +NS_NewHTMLButton(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aManager) +{ + return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Button); } nsresult NS_NewHTMLInputSubmit(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { - return CreateButton(aInstancePtrResult, aTag, aManager, kInputButtonSubmit); + return CreateButton(aInstancePtrResult, aTag, aManager, kButton_InputSubmit); } nsresult NS_NewHTMLInputReset(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { - return CreateButton(aInstancePtrResult, aTag, aManager, kInputButtonReset); + return CreateButton(aInstancePtrResult, aTag, aManager, kButton_InputReset); +} + +nsresult +NS_NewHTMLInputHidden(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aManager) +{ + return CreateButton(aInstancePtrResult, aTag, aManager, kButton_InputHidden); } diff --git a/mozilla/layout/html/forms/src/nsInputCheckbox.cpp b/mozilla/layout/html/forms/src/nsInputCheckbox.cpp index 0fe4c00a76d..5a2b8b7224b 100644 --- a/mozilla/layout/html/forms/src/nsInputCheckbox.cpp +++ b/mozilla/layout/html/forms/src/nsInputCheckbox.cpp @@ -37,20 +37,21 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds); - - virtual void InitializeWidget(nsIView *aView); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); virtual const nsIID GetCID(); virtual const nsIID GetIID(); - virtual void MouseClicked(); + virtual void MouseClicked(nsIPresContext* aPresContext); protected: virtual ~nsInputCheckboxFrame(); PRBool mCacheState; + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize); }; nsInputCheckboxFrame::nsInputCheckboxFrame(nsIContent* aContent, @@ -80,13 +81,15 @@ nsInputCheckboxFrame::GetCID() return kCheckboxCID; } -void -nsInputCheckboxFrame::PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds) +void +nsInputCheckboxFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize) { nsInputCheckbox* content = (nsInputCheckbox *)mContent; // this must be an nsCheckbox - // get the state + // get the intial state nsHTMLValue value; nsContentAttr result = content->GetAttribute(nsHTMLAtoms::checked, value); if (result != eContentAttr_NotThere) { @@ -94,12 +97,14 @@ nsInputCheckboxFrame::PreInitializeWidget(nsIPresContext* aPresContext, } float p2t = aPresContext->GetPixelsToTwips(); - aBounds.width = (int)(13 * p2t); - aBounds.height = (int)(13 * p2t); + aDesiredLayoutSize.width = (int)(13 * p2t); + aDesiredLayoutSize.height = (int)(13 * p2t); + aDesiredWidgetSize.width = aDesiredLayoutSize.width; + aDesiredWidgetSize.height = aDesiredLayoutSize.height; } void -nsInputCheckboxFrame::InitializeWidget(nsIView *aView) +nsInputCheckboxFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { nsICheckButton* checkbox; if (NS_OK == GetWidget(aView, (nsIWidget **)&checkbox)) { @@ -109,7 +114,7 @@ nsInputCheckboxFrame::InitializeWidget(nsIView *aView) } void -nsInputCheckboxFrame::MouseClicked() +nsInputCheckboxFrame::MouseClicked(nsIPresContext* aPresContext) { nsICheckButton* checkbox; nsIView* view; @@ -129,13 +134,11 @@ nsInputCheckboxFrame::MouseClicked() nsInputCheckbox::nsInputCheckbox(nsIAtom* aTag, nsIFormManager* aManager) : nsInput(aTag, aManager) { + mChecked = PR_FALSE; } nsInputCheckbox::~nsInputCheckbox() { - if (nsnull != mValue) { - delete mValue; - } } @@ -174,7 +177,7 @@ nsInputCheckbox::Reset() { nsICheckButton* checkbox = (nsICheckButton *)GetWidget(); if (nsnull != checkbox) { - checkbox->SetState(mInitialChecked); + checkbox->SetState(mChecked); } } @@ -196,14 +199,7 @@ void nsInputCheckbox::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) { if (aAttribute == nsHTMLAtoms::checked) { - mInitialChecked = PR_TRUE; - } - else if (aAttribute == nsHTMLAtoms::value) { - if (nsnull == mValue) { - mValue = new nsString(aValue); - } else { - *mValue = aValue; - } + mChecked = PR_TRUE; } else { nsInput::SetAttribute(aAttribute, aValue); @@ -213,26 +209,16 @@ void nsInputCheckbox::SetAttribute(nsIAtom* aAttribute, nsContentAttr nsInputCheckbox::GetAttribute(nsIAtom* aAttribute, nsHTMLValue& aResult) const { - nsContentAttr ca = eContentAttr_NotThere; aResult.Reset(); if (aAttribute == nsHTMLAtoms::checked) { - if (mInitialChecked) { - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::value) { - if (nsnull != mValue) { - aResult.Set(*mValue); - ca = eContentAttr_HasValue; - } + return GetCacheAttribute(mChecked, aResult); } else { - ca = nsInput::GetAttribute(aAttribute, aResult); + return nsInput::GetAttribute(aAttribute, aResult); } - return ca; } -NS_HTML nsresult +nsresult NS_NewHTMLInputCheckbox(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { diff --git a/mozilla/layout/html/forms/src/nsInputCheckbox.h b/mozilla/layout/html/forms/src/nsInputCheckbox.h index 5fc5da0a34a..3070abefbdd 100644 --- a/mozilla/layout/html/forms/src/nsInputCheckbox.h +++ b/mozilla/layout/html/forms/src/nsInputCheckbox.h @@ -48,8 +48,7 @@ protected: virtual void GetType(nsString& aResult) const; - nsString* mValue; - PRBool mInitialChecked; // initial checked flag value + PRBool mChecked; // initial checked flag value }; #endif diff --git a/mozilla/layout/html/forms/src/nsInputFile.cpp b/mozilla/layout/html/forms/src/nsInputFile.cpp index 721532f754e..85343603ed0 100644 --- a/mozilla/layout/html/forms/src/nsInputFile.cpp +++ b/mozilla/layout/html/forms/src/nsInputFile.cpp @@ -34,7 +34,7 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void InitializeWidget(nsIView *aView); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); protected: virtual ~nsInputFileFrame(); @@ -53,7 +53,7 @@ nsInputFileFrame::~nsInputFileFrame() void -nsInputFileFrame::InitializeWidget(nsIView *aView) +nsInputFileFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { } @@ -86,60 +86,8 @@ void nsInputFile::GetType(nsString& aResult) const aResult = "file"; } -void nsInputFile::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) -{ - if (aAttribute == nsHTMLAtoms::size) { - nsHTMLValue value; - ParseValue(aValue, 1, value); - mSize = value.GetIntValue(); - } - else if (aAttribute == nsHTMLAtoms::maxlength) { - nsHTMLValue value; - ParseValue(aValue, 1, value);/* XXX nav doesn't clamp; what does it do with illegal values? */ - mMaxLength = value.GetIntValue(); - } - else if (aAttribute == nsHTMLAtoms::value) { - if (nsnull == mValue) { - mValue = new nsString(aValue); - } else { - *mValue = aValue; - } - } - else { - nsInput::SetAttribute(aAttribute, aValue); - } -} -nsContentAttr nsInputFile::GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const -{ - nsContentAttr ca = eContentAttr_NotThere; - aResult.Reset(); - if (aAttribute == nsHTMLAtoms::size) { - if (0 < mSize) { - aResult.Set(mSize, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::maxlength) { - if (0 < mMaxLength) { - aResult.Set(mMaxLength, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::value) { - if (nsnull != mValue) { - aResult.Set(*mValue); - ca = eContentAttr_HasValue; - } - } - else { - ca = nsInput::GetAttribute(aAttribute, aResult); - } - return ca; -} - -NS_HTML nsresult +nsresult NS_NewHTMLInputFile(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { diff --git a/mozilla/layout/html/forms/src/nsInputFile.h b/mozilla/layout/html/forms/src/nsInputFile.h index 55116be376f..d57f63fbf60 100644 --- a/mozilla/layout/html/forms/src/nsInputFile.h +++ b/mozilla/layout/html/forms/src/nsInputFile.h @@ -33,11 +33,6 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); - - virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const; - protected: virtual ~nsInputFile(); diff --git a/mozilla/layout/html/forms/src/nsInputFrame.cpp b/mozilla/layout/html/forms/src/nsInputFrame.cpp index acc47a3ce0d..265cc2ae4e9 100644 --- a/mozilla/layout/html/forms/src/nsInputFrame.cpp +++ b/mozilla/layout/html/forms/src/nsInputFrame.cpp @@ -19,7 +19,7 @@ #include "nsInput.h" #include "nsInputFrame.h" #include "nsHTMLParts.h" -#include "nsHTMLTagContent.h" +#include "nsHTMLContainer.h" #include "nsIRenderingContext.h" #include "nsIPresShell.h" #include "nsIPresContext.h" @@ -34,11 +34,29 @@ #include "nsViewsCID.h" #include "nsRepository.h" #include "nsGUIEvent.h" - +#include "nsIFontCache.h" +#include "nsIFontMetrics.h" +#include "nsIFormManager.h" +#include "nsIDeviceContext.h" +#include "nsHTMLAtoms.h" #include "nsIButton.h" // remove this when GetCID is pure virtual #include "nsICheckButton.h" //remove this #include "nsITextWidget.h" //remove this #include "nsISupports.h" +#include "nsHTMLForms.h" + +static NS_DEFINE_IID(kStyleFontSID, NS_STYLEFONT_SID); +static NS_DEFINE_IID(kStyleMoleculeSID, NS_STYLEMOLECULE_SID); + +struct nsInputCallbackData +{ + nsIPresContext* mPresContext; + nsInputFrame* mFrame; + nsInputCallbackData(nsIPresContext* aPresContext, nsInputFrame* aFrame) + :mPresContext(aPresContext), mFrame(aFrame) + { + } +}; nsInputFrame::nsInputFrame(nsIContent* aContent, PRInt32 aIndexInParent, @@ -83,8 +101,15 @@ nsInputFrame::Paint(nsIPresContext& aPresContext, view->SetPosition(offset.x, offset.y); // initially the widget was created as hidden - if (nsViewVisibility_kHide == view->GetVisibility()) + if (nsViewVisibility_kHide == view->GetVisibility()) { + nsInput* content; + GetContent((nsIContent *&) content); + content->GetFormManager()->Init(PR_FALSE); // this only inits the 1st time + NS_RELEASE(content); + view->SetVisibility(nsViewVisibility_kShow); + PostCreateWidget(&aPresContext, view); + } } else { NS_ASSERTION(0, "could not get widget"); } @@ -105,27 +130,37 @@ nsInputFrame::BoundsAreSet() } } +PRBool +nsInputFrame::IsHidden() +{ + nsInput* content = (nsInput *)mContent; + return content->IsHidden(); +} + +void +nsInputFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize) +{ + // get the css size and let the frame use or override it + nsSize styleSize; + GetStyleSize(*aPresContext, aMaxSize, styleSize); + + // subclasses should always override this method, but if not and no css, make it small + aDesiredLayoutSize.width = (styleSize.width > CSS_NOTSET) ? styleSize.width : 144; + aDesiredLayoutSize.height = (styleSize.height > CSS_NOTSET) ? styleSize.height : 144; + aDesiredWidgetSize.width = aDesiredLayoutSize.width; + aDesiredWidgetSize.height = aDesiredLayoutSize.height; +} void nsInputFrame::GetDesiredSize(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, const nsSize& aMaxSize) { - if (!BoundsAreSet()) { - PreInitializeWidget(aPresContext, mCacheBounds); // sets mCacheBounds - } - aDesiredSize.width = mCacheBounds.width; - aDesiredSize.height = mCacheBounds.height; -} - -void -nsInputFrame::PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds) -{ - // this should always be overridden by subclasses, but if not make it 10 x 10 - float p2t = aPresContext->GetPixelsToTwips(); - aBounds.width = (int)(10 * p2t); - aBounds.height = (int)(10 * p2t); + nsSize ignore; + GetDesiredSize(aPresContext, aMaxSize, aDesiredSize, ignore); } NS_METHOD @@ -135,18 +170,20 @@ nsInputFrame::ResizeReflow(nsIPresContext* aPresContext, nsSize* aMaxElementSize, ReflowStatus& aStatus) { - // XXX add in code to check for width/height being set via css - // and if set use them instead of calling GetDesiredSize. - nsIView* view; GetView(view); + if (nsnull == view) { static NS_DEFINE_IID(kViewCID, NS_VIEW_CID); static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); + // make sure the style context is set + if (nsnull == mStyleContext) { + GetStyleContext(aPresContext, mStyleContext); + } nsresult result = - NSRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view);// need to release + NSRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&view);// need to release if (NS_OK != result) { NS_ASSERTION(0, "Could not create view for button"); aStatus = frNotComplete; @@ -155,9 +192,13 @@ nsInputFrame::ResizeReflow(nsIPresContext* aPresContext, nsIPresShell *presShell = aPresContext->GetShell(); // need to release nsIViewManager *viewMan = presShell->GetViewManager(); // need to release - PreInitializeWidget(aPresContext, mCacheBounds); // sets mCacheBounds - //float t2p = aPresContext->GetTwipsToPixels(); - nsRect boundBox(0, 0, mCacheBounds.width, mCacheBounds.height); + nsReflowMetrics layoutSize; + nsSize widgetSize; + GetDesiredSize(aPresContext, aMaxSize, layoutSize, widgetSize); + mCacheBounds.width = widgetSize.width; // YYY what about caching widget size? + mCacheBounds.height = widgetSize.height; + + nsRect boundBox(0, 0, widgetSize.width, widgetSize.height); nsIFrame* parWithView; nsIView *parView; @@ -166,9 +207,13 @@ nsInputFrame::ResizeReflow(nsIPresContext* aPresContext, parWithView->GetView(parView); const nsIID id = GetCID(); + nsInputWidgetData* initData = GetWidgetInitData(); // needs to be deleted // initialize the view as hidden since we don't know the (x,y) until Paint - result = view->Init(viewMan, boundBox, parView, &id, nsnull, 0, nsnull, + result = view->Init(viewMan, boundBox, parView, &id, initData, nsnull, 0, nsnull, 1.0f, nsViewVisibility_kHide); + if (nsnull != initData) { + delete(initData); + } if (NS_OK != result) { NS_ASSERTION(0, "widget initialization failed"); aStatus = frNotComplete; @@ -188,7 +233,7 @@ nsInputFrame::ResizeReflow(nsIPresContext* aPresContext, viewMan->InsertChild(parView, view, 0); SetView(view); - InitializeWidget(view); + //PostCreateWidget(aPresContext, view); NS_IF_RELEASE(parView); NS_IF_RELEASE(view); @@ -209,6 +254,17 @@ nsInputFrame::ResizeReflow(nsIPresContext* aPresContext, return NS_OK; } +nsInputWidgetData* +nsInputFrame::GetWidgetInitData() +{ + return nsnull; +} + +void +nsInputFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) +{ +} + nsresult nsInputFrame::GetWidget(nsIView* aView, nsIWidget** aWidget) { @@ -242,11 +298,19 @@ NS_METHOD nsInputFrame::HandleEvent(nsIPresContext& aPresContext, // make sure that the widget in the event is this static NS_DEFINE_IID(kSupportsIID, NS_ISUPPORTS_IID); nsIWidget* thisWidget; + nsIView* view; GetView(view); + if (view == nsnull) { + return nsEventStatus_eIgnore; + } + nsresult result = GetWidget(view, &thisWidget); nsISupports* thisWidgetSup; result = thisWidget->QueryInterface(kSupportsIID, (void **)&thisWidgetSup); + if (thisWidget == nsnull) { + return nsEventStatus_eIgnore; + } nsISupports* eventWidgetSup; result = aEvent->widget->QueryInterface(kSupportsIID, (void **)&eventWidgetSup); @@ -277,7 +341,7 @@ NS_METHOD nsInputFrame::HandleEvent(nsIPresContext& aPresContext, widget->SetFocus(); NS_RELEASE(widget); NS_RELEASE(view); */ - MouseClicked(); + MouseClicked(&aPresContext); //return PR_FALSE; } mLastMouseState = eMouseEnter; @@ -286,12 +350,183 @@ NS_METHOD nsInputFrame::HandleEvent(nsIPresContext& aPresContext, mLastMouseState = eMouseNone; break; } - aEventStatus = nsEventStatus_eIgnore; - return NS_OK; + return nsEventStatus_eConsumeDoDefault; +} + +void nsInputFrame::GetStyleSize(nsIPresContext& aPresContext, const nsSize& aMaxSize, nsSize& aSize) +{ + nsInput* input; + GetContent((nsIContent *&) input); // this must be an nsInput + nsStyleMolecule* mol = (nsStyleMolecule*)mStyleContext->GetData(kStyleMoleculeSID); + +//printf("\n ** %d %d", mol->fixedWidth, mol->proportionalWidth); + // set the width, height + aSize.width = mol->fixedWidth; + if ((CSS_NOTSET == aSize.width) && (CSS_NOTSET != mol->proportionalWidth)) { + aSize.width = (aMaxSize.width * mol->proportionalWidth) / 100; + } + aSize.height = mol->fixedHeight; + if ((CSS_NOTSET == aSize.height) && (CSS_NOTSET != mol->proportionalHeight)) { + aSize.height = (aMaxSize.height * mol->proportionalHeight) / 100; + } + + NS_RELEASE(input); +} + +PRInt32 +nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsIFrame* aFrame, + const nsString& aString, nsSize& aSize) +{ + //printf("\n GetTextSize %s", aString.ToNewCString()); + nsIStyleContext* styleContext; + aFrame->GetStyleContext(&aPresContext, styleContext); + nsStyleFont* styleFont = (nsStyleFont*)styleContext->GetData(kStyleFontSID); + NS_RELEASE(styleContext); + nsIDeviceContext* deviceContext = aPresContext.GetDeviceContext(); + nsIFontCache* fontCache = deviceContext->GetFontCache(); + + nsIFontMetrics* fontMet = fontCache->GetMetricsFor(styleFont->mFont); + aSize.width = fontMet->GetWidth(aString); + aSize.height = fontMet->GetHeight() + fontMet->GetLeading(); + + PRInt32 charWidth = fontMet->GetWidth("W"); + + NS_RELEASE(fontMet); + NS_RELEASE(fontCache); + NS_RELEASE(deviceContext); + + return charWidth; +} + +PRInt32 +nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsIFrame* aFrame, + PRInt32 aNumChars, nsSize& aSize) +{ + nsAutoString val; + for (int i = 0; i < aNumChars; i++) { + val += 'e'; // use a typical char, what is the avg width character? + } + return GetTextSize(aPresContext, aFrame, val, aSize); +} + +PRInt32 +nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, + const nsSize& aCSSSize, nsInputDimensionSpec& aSpec, + nsSize& aBounds, PRBool& aWidthExplicit, + PRBool& aHeightExplicit, PRInt32& aRowHeight) +{ + PRInt32 charWidth = 0; + aWidthExplicit = PR_FALSE; + aHeightExplicit = PR_FALSE; + + aBounds.width = CSS_NOTSET; + aBounds.height = CSS_NOTSET; + nsSize textSize(0,0); + + nsInput* content; + aFrame->GetContent((nsIContent *&) content); + nsAutoString valAttr; + nsContentAttr valStatus = eContentAttr_NotThere; + if (nsnull != aSpec.mColValueAttr) { + valStatus = content->GetAttribute(aSpec.mColValueAttr, valAttr); + } + PRInt32 colAttr; + nsContentAttr colStatus = eContentAttr_NotThere; + if (nsnull != aSpec.mColSizeAttr) { + colStatus = content->GetAttribute(aSpec.mColSizeAttr, colAttr); + } + + if (eContentAttr_HasValue == colStatus) { // col attr will provide width + if (aSpec.mColSizeAttrInPixels) { + float p2t = aPresContext->GetPixelsToTwips(); + aBounds.width = (int) (((float)colAttr) * p2t); + } + else { + charWidth = GetTextSize(*aPresContext, aFrame, colAttr, aBounds); + aRowHeight = aBounds.height; + } + if (aSpec.mColSizeAttrInPixels) { + aWidthExplicit = PR_TRUE; + } + } + else { + if (CSS_NOTSET != aCSSSize.width) { // css provides width + aBounds.width = aCSSSize.width; + aWidthExplicit = PR_TRUE; + } + else { + if (eContentAttr_HasValue == valStatus) { // use width of initial value if specified + charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds); + } + else if (aSpec.mColDefaultSizeInPixels) { // use default width in pixels + charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds); + aBounds.width = aSpec.mColDefaultSize; + } + else { // use default width in num characters + charWidth = GetTextSize(*aPresContext, aFrame, aSpec.mColDefaultSize, aBounds); + } + aRowHeight = aBounds.height; + } + } + + PRInt32 rowAttr = CSS_NOTSET; + nsContentAttr rowStatus = eContentAttr_NotThere; + if (nsnull != aSpec.mRowSizeAttr) { + rowStatus = content->GetAttribute(aSpec.mRowSizeAttr, rowAttr); + } + + if (eContentAttr_HasValue == rowStatus) { // row attr will provide height + if (0 == charWidth) { + charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize); + aBounds.height = textSize.height * rowAttr; + aRowHeight = textSize.height; + } + else { + aBounds.height = aBounds.height * rowAttr; + } + } + else if (CSS_NOTSET != aCSSSize.height) { // css provides height + aBounds.height = aCSSSize.height; + aHeightExplicit = PR_TRUE; + } + else { // use default height in num lines + if (0 == charWidth) { + charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize); + aBounds.height = textSize.height * aSpec.mRowDefaultSize; + aRowHeight = textSize.height; + } + else { + aBounds.height = aBounds.height * aSpec.mRowDefaultSize; + } + } + + if (0 == charWidth) { + charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize); + aRowHeight = textSize.height; + } + + // add padding to width if width wasn't specified either from css or size attr + if (!aWidthExplicit) { + aBounds.width += charWidth; + } + + NS_RELEASE(content); + + // return number of rows that the calcuated size can support + return (int)(((float)aBounds.height) / ((float)aRowHeight)); + +} + + +nsFont& +nsInputFrame::GetFont(nsIPresContext* aPresContext) +{ + nsStyleFont* styleFont = (nsStyleFont*)mStyleContext->GetData(kStyleFontSID); + + return styleFont->mFont; } - diff --git a/mozilla/layout/html/forms/src/nsInputFrame.h b/mozilla/layout/html/forms/src/nsInputFrame.h index 96c6adf8499..d9b002f38ab 100644 --- a/mozilla/layout/html/forms/src/nsInputFrame.h +++ b/mozilla/layout/html/forms/src/nsInputFrame.h @@ -19,12 +19,20 @@ #ifndef nsInputFrame_h___ #define nsInputFrame_h___ -#include "nsHTMLTagContent.h" +#include "nsHTMLContainer.h" #include "nsISupports.h" #include "nsIWidget.h" #include "nsLeafFrame.h" class nsIView; +class nsIPresContext; + +struct nsInputWidgetData { + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}; /** * Enumeration of possible mouse states used to detect mouse clicks @@ -36,6 +44,29 @@ enum nsMouseState { eMouseUp }; +struct nsInputDimensionSpec +{ + nsIAtom* mColSizeAttr; + PRBool mColSizeAttrInPixels; + nsIAtom* mColValueAttr; + PRInt32 mColDefaultSize; + PRBool mColDefaultSizeInPixels; + nsIAtom* mRowSizeAttr; + PRInt32 mRowDefaultSize; + + nsInputDimensionSpec(nsIAtom* aColSizeAttr, PRBool aColSizeAttrInPixels, + nsIAtom* aColValueAttr, PRInt32 aColDefaultSize, + PRBool aColDefaultSizeInPixels, + nsIAtom* aRowSizeAttr, PRInt32 aRowDefaultSize) + : mColSizeAttr(aColSizeAttr), mColSizeAttrInPixels(aColSizeAttrInPixels), + mColValueAttr(aColValueAttr), mColDefaultSize(aColDefaultSize), + mColDefaultSizeInPixels(aColDefaultSizeInPixels), + mRowSizeAttr(aRowSizeAttr), mRowDefaultSize(aRowDefaultSize) + { + } + +}; + /** * nsInputFrame is the base class for frames of form controls. It * provides a uniform way of creating widgets, resizing, and painting. @@ -53,6 +84,10 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); + static PRInt32 CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, + const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec, + nsSize& aBounds, PRBool& aWidthExplicit, + PRBool& aHeightExplicit, PRInt32& aRowSize); // nsLeafFrame overrides /** @@ -62,6 +97,9 @@ public: NS_IMETHOD HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus); + + virtual PRBool IsHidden(); + /** * Draw this frame within the context of a presentation context and rendering context * @see nsIFrame::Paint @@ -80,7 +118,7 @@ public: nsSize* aMaxElementSize, ReflowStatus& aStatus); - // New Behavior + // new behavior /** * Get the class id of the widget associated with this frame @@ -102,31 +140,38 @@ public: */ virtual nsresult GetWidget(nsIView* aView, nsIWidget** aWidget); - /** - * Perform opertations after the widget associated with this frame has been - * fully constructed. - */ - virtual void InitializeWidget(nsIView *aView) = 0; - /** * Respond to a mouse click (e.g. mouse enter, mouse down, mouse up) */ - virtual void MouseClicked() {} + virtual void MouseClicked(nsIPresContext* aPresContext) {} /** - * Perform operations before the widget associated with this frame has been - * constructed. - * @param aPresContext the presentation context - * @param aBounds the bounds of this frame. It will be set by this method. + * Perform opertations after the widget associated with this frame has been + * created. */ - virtual void PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); + + /** + * Perform opertations before the widget associated with this frame has been + * created. + */ + virtual nsInputWidgetData* GetWidgetInitData(); + + static PRInt32 GetTextSize(nsIPresContext& aContext, nsIFrame* aFrame, + const nsString& aString, nsSize& aSize); + static PRInt32 GetTextSize(nsIPresContext& aContext, nsIFrame* aFrame, + PRInt32 aNumChars, nsSize& aSize); protected: virtual ~nsInputFrame(); /** + * Return PR_TRUE if the bounds of this frame have been set + */ + PRBool BoundsAreSet(); + + /** * Get the size that this frame would occupy without any constraints * @param aPresContext the presentation context * @param aDesiredSize the size desired by this frame, to be set by this method @@ -135,13 +180,26 @@ protected: virtual void GetDesiredSize(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredSize, const nsSize& aMaxSize); - /** - * Return PR_TRUE if the bounds of this frame have been set + + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize); + + nsFont& GetFont(nsIPresContext* aPresContext); + + /** + * Get the width and height of this control based on CSS + * @param aPresContext the presentation context + * @param aMaxSize the maximum size that this frame can have + * @param aSize the size that this frame wants, set by this method. values of -1 + * for aSize.width or aSize.height indicate unset values. */ - PRBool BoundsAreSet(); + void GetStyleSize(nsIPresContext& aContext, const nsSize& aMaxSize, nsSize& aSize); nsSize mCacheBounds; nsMouseState mLastMouseState; }; #endif + diff --git a/mozilla/layout/html/forms/src/nsInputHidden.cpp b/mozilla/layout/html/forms/src/nsInputHidden.cpp deleted file mode 100644 index 96998ef7d0f..00000000000 --- a/mozilla/layout/html/forms/src/nsInputHidden.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#include "nsInputHidden.h" -#include "nsInputFrame.h" -#include "nsIContent.h" -#include "prtypes.h" -#include "nsIFrame.h" -#include "nsISupports.h" -#include "nsIAtom.h" -#include "nsIPresContext.h" -#include "nsIHTMLContent.h" -#include "nsHTMLIIDs.h" -#include "nsHTMLAtoms.h" - -class nsInputHiddenFrame : public nsInputFrame { -public: - nsInputHiddenFrame(nsIContent* aContent, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame); - - virtual void InitializeWidget(nsIView *aView); - -protected: - virtual ~nsInputHiddenFrame(); -}; - -nsInputHiddenFrame::nsInputHiddenFrame(nsIContent* aContent, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame) - : nsInputFrame(aContent, aIndexInParent, aParentFrame) -{ -} - -nsInputHiddenFrame::~nsInputHiddenFrame() -{ -} - - -void -nsInputHiddenFrame::InitializeWidget(nsIView *aView) -{ -} - -// nsInputHidden - -nsInputHidden::nsInputHidden(nsIAtom* aTag, nsIFormManager* aManager) - : nsInput(aTag, aManager) -{ -} - -nsInputHidden::~nsInputHidden() -{ -} - -nsIFrame* -nsInputHidden::CreateFrame(nsIPresContext* aPresContext, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame) -{ - nsIFrame* rv = new nsInputHiddenFrame(this, aIndexInParent, aParentFrame); - return rv; -} - -void nsInputHidden::GetType(nsString& aResult) const -{ - aResult = "hidden"; -} - -void nsInputHidden::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) -{ - if (aAttribute == nsHTMLAtoms::value) { - if (nsnull == mValue) { - mValue = new nsString(aValue); - } else { - mValue->SetLength(0); - mValue->Append(aValue); - } - } - else if (aAttribute == nsHTMLAtoms::width) { - nsHTMLValue value; - ParseValue(aValue, 0, 1000, value); - mWidth = value.GetIntValue(); - } - else if (aAttribute == nsHTMLAtoms::height) { - nsHTMLValue value; - ParseValue(aValue, 0, 1000, value); - mHeight = value.GetIntValue(); - } - else { - nsInput::SetAttribute(aAttribute, aValue); - } -} - -nsContentAttr nsInputHidden::GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const -{ - nsContentAttr ca = eContentAttr_NotThere; - aResult.Reset(); - if (aAttribute == nsHTMLAtoms::value) { - if (nsnull != mValue) { - aResult.Set(*mValue); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::width) { - if (0 <= mWidth) { - aResult.Set(mWidth, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::height) { - if (0 <= mHeight) { - aResult.Set(mHeight, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else { - ca = nsInput::GetAttribute(aAttribute, aResult); - } - return ca; -} - -NS_HTML nsresult -NS_NewHTMLInputHidden(nsIHTMLContent** aInstancePtrResult, - nsIAtom* aTag, nsIFormManager* aManager) -{ - NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); - if (nsnull == aInstancePtrResult) { - return NS_ERROR_NULL_POINTER; - } - - nsIHTMLContent* it = new nsInputHidden(aTag, aManager); - - if (nsnull == it) { - return NS_ERROR_OUT_OF_MEMORY; - } - return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); -} - diff --git a/mozilla/layout/html/forms/src/nsInputHidden.h b/mozilla/layout/html/forms/src/nsInputHidden.h deleted file mode 100644 index 2d736f6ed04..00000000000 --- a/mozilla/layout/html/forms/src/nsInputHidden.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#ifndef nsInputHidden_h___ -#define nsInputHidden_h___ - -#include "nsInput.h" -class nsIAtom; -class nsString; - -// this class definition will move to nsInputHidden.cpp - -class nsInputHidden : public nsInput { -public: - nsInputHidden (nsIAtom* aTag, nsIFormManager* aManager); - - virtual nsIFrame* CreateFrame(nsIPresContext* aPresContext, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame); - - virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); - - virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const; - -protected: - virtual ~nsInputHidden(); - - virtual void GetType(nsString& aResult) const; - - // XXX save code and subclass from nsInputButton? - nsString* mValue; - PRInt32 mWidth; - PRInt32 mHeight; -}; - -#endif diff --git a/mozilla/layout/html/forms/src/nsInputImage.cpp b/mozilla/layout/html/forms/src/nsInputImage.cpp index ac6c07cf7ad..e8d37de61eb 100644 --- a/mozilla/layout/html/forms/src/nsInputImage.cpp +++ b/mozilla/layout/html/forms/src/nsInputImage.cpp @@ -33,7 +33,7 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void InitializeWidget(nsIView *aView); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); protected: virtual ~nsInputImageFrame(); @@ -52,7 +52,7 @@ nsInputImageFrame::~nsInputImageFrame() void -nsInputImageFrame::InitializeWidget(nsIView *aView) +nsInputImageFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { } @@ -82,23 +82,7 @@ void nsInputImage::GetType(nsString& aResult) const aResult = "image"; } -void nsInputImage::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) -{ - // XXX need to read nav4 code first - nsInput::SetAttribute(aAttribute, aValue); -} - -nsContentAttr nsInputImage::GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const -{ - // XXX need to read nav4 code first - nsContentAttr ca = eContentAttr_NotThere; - aResult.Reset(); - ca = nsInput::GetAttribute(aAttribute, aResult); - return ca; -} - -NS_HTML nsresult +nsresult NS_NewHTMLInputImage(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { diff --git a/mozilla/layout/html/forms/src/nsInputImage.h b/mozilla/layout/html/forms/src/nsInputImage.h index ea3e842f3df..44f3663c721 100644 --- a/mozilla/layout/html/forms/src/nsInputImage.h +++ b/mozilla/layout/html/forms/src/nsInputImage.h @@ -32,13 +32,8 @@ public: virtual nsIFrame* CreateFrame(nsIPresContext* aPresContext, PRInt32 aIndexInParent, nsIFrame* aParentFrame); - - virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); - - virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, - nsHTMLValue& aResult) const; - protected: + virtual ~nsInputImage(); virtual void GetType(nsString& aResult) const; diff --git a/mozilla/layout/html/forms/src/nsInputPassword.cpp b/mozilla/layout/html/forms/src/nsInputPassword.cpp deleted file mode 100644 index 7ffed0a3629..00000000000 --- a/mozilla/layout/html/forms/src/nsInputPassword.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#include "nsInputPassword.h" -#include "nsInputFrame.h" -#include "nsIContent.h" -#include "prtypes.h" -#include "nsIFrame.h" -#include "nsISupports.h" -#include "nsIAtom.h" -#include "nsIPresContext.h" -#include "nsIHTMLContent.h" -#include "nsHTMLIIDs.h" - -#include "nsIStyleContext.h" -#include "nsIFontMetrics.h" -#include "nsWidgetsCID.h" -#include "nsITextWidget.h" - -static NS_DEFINE_IID(kStyleFontSID, NS_STYLEFONT_SID); - -class nsInputPasswordFrame : public nsInputFrame { -public: - nsInputPasswordFrame(nsIContent* aContent, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame); - - virtual void PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds); - - virtual void InitializeWidget(nsIView *aView); - - virtual const nsIID GetCID(); - - virtual const nsIID GetIID(); - -protected: - virtual ~nsInputPasswordFrame(); - nsString mCacheValue; -}; - -nsInputPasswordFrame::nsInputPasswordFrame(nsIContent* aContent, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame) - : nsInputFrame(aContent, aIndexInParent, aParentFrame) -{ -} - -nsInputPasswordFrame::~nsInputPasswordFrame() -{ -} - -const nsIID -nsInputPasswordFrame::GetIID() -{ - static NS_DEFINE_IID(kTextIID, NS_ITEXTWIDGET_IID); - return kTextIID; -} - -const nsIID -nsInputPasswordFrame::GetCID() -{ - static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID); - return kTextCID; -} - -void -nsInputPasswordFrame::PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds) -{ - nsInputText* content = (nsInputText *)mContent; - - // get the value of the text - if (nsnull != content->mValue) { - mCacheValue = *content->mValue; - } else { - mCacheValue = ""; - } - - nsIStyleContext* styleContext = mStyleContext; - nsStyleFont* styleFont = (nsStyleFont*)styleContext->GetData(kStyleFontSID); - nsIFontMetrics* fm = aPresContext->GetMetricsFor(styleFont->mFont); - - float p2t = aPresContext->GetPixelsToTwips(); - -#define DEFAULT_SIZE 21 - PRInt32 size = content->mSize; - if (size <= 0) { - size = DEFAULT_SIZE; - } - - // XXX 6 should come from widget: we tell widget what the font is, - // tell it mSize, let it tell us it's width and height - - aBounds.width = size * fm->GetWidth(' ') + nscoord(6 * p2t); - aBounds.height = fm->GetHeight() + nscoord(6 * p2t); - - NS_RELEASE(fm); -} - -void -nsInputPasswordFrame::InitializeWidget(nsIView *aView) -{ - nsITextWidget* text; - if (NS_OK == GetWidget(aView, (nsIWidget **)&text)) { - text->SetText(mCacheValue); - NS_RELEASE(text); - } -} - -//---------------------------------------------------------------------- -// nsInputPassword - -nsInputPassword::nsInputPassword(nsIAtom* aTag, nsIFormManager* aManager) - : nsInputText(aTag, aManager) -{ -} - -nsInputPassword::~nsInputPassword() -{ -} - -nsIFrame* -nsInputPassword::CreateFrame(nsIPresContext* aPresContext, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame) -{ - nsIFrame* rv = new nsInputPasswordFrame(this, aIndexInParent, aParentFrame); - return rv; -} - -NS_HTML nsresult -NS_NewHTMLInputPassword(nsIHTMLContent** aInstancePtrResult, - nsIAtom* aTag, nsIFormManager* aManager) -{ - NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); - if (nsnull == aInstancePtrResult) { - return NS_ERROR_NULL_POINTER; - } - - nsIHTMLContent* it = new nsInputPassword(aTag, aManager); - - if (nsnull == it) { - return NS_ERROR_OUT_OF_MEMORY; - } - return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); -} - diff --git a/mozilla/layout/html/forms/src/nsInputPassword.h b/mozilla/layout/html/forms/src/nsInputPassword.h deleted file mode 100644 index 4d049d308ad..00000000000 --- a/mozilla/layout/html/forms/src/nsInputPassword.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public License - * Version 1.0 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#ifndef nsInputPassword_h___ -#define nsInputPassword_h___ - -#include "nsInputText.h" -class nsIAtom; -class nsString; - -// this class definition will move to nsInputPassword.cpp - -class nsInputPassword : public nsInputText { -public: - nsInputPassword (nsIAtom* aTag, nsIFormManager* aManager); - - virtual nsIFrame* CreateFrame(nsIPresContext* aPresContext, - PRInt32 aIndexInParent, - nsIFrame* aParentFrame); - -protected: - virtual ~nsInputPassword(); -}; - -#endif - - diff --git a/mozilla/layout/html/forms/src/nsInputRadio.cpp b/mozilla/layout/html/forms/src/nsInputRadio.cpp index 379c90c7be0..290c2023fd3 100644 --- a/mozilla/layout/html/forms/src/nsInputRadio.cpp +++ b/mozilla/layout/html/forms/src/nsInputRadio.cpp @@ -29,6 +29,9 @@ #include "nsIRadioButton.h" #include "nsWidgetsCID.h" #include "nsSize.h" +#include "nsHTMLAtoms.h" +#include "nsIFormManager.h" +#include "nsIView.h" class nsInputRadioFrame : public nsInputFrame { public: @@ -36,17 +39,22 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds); - - virtual void InitializeWidget(nsIView *aView); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); virtual const nsIID GetCID(); virtual const nsIID GetIID(); + virtual void MouseClicked(nsIPresContext* aPresContext); + protected: + virtual ~nsInputRadioFrame(); + + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize); }; nsInputRadioFrame::nsInputRadioFrame(nsIContent* aContent, @@ -76,30 +84,94 @@ nsInputRadioFrame::GetCID() } void -nsInputRadioFrame::PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds) +nsInputRadioFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize) { float p2t = aPresContext->GetPixelsToTwips(); - aBounds.width = (int)(12 * p2t); - aBounds.height = (int)(12 * p2t); + aDesiredLayoutSize.width = (int)(12 * p2t); + aDesiredLayoutSize.height = (int)(12 * p2t); + aDesiredWidgetSize.width = aDesiredLayoutSize.width; + aDesiredWidgetSize.height = aDesiredLayoutSize.height; } void -nsInputRadioFrame::InitializeWidget(nsIView *aView) +nsInputRadioFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { + nsInputRadio* content = (nsInputRadio *)mContent; + PRInt32 checkedAttr; + nsContentAttr result = ((nsInput *)content)->GetAttribute(nsHTMLAtoms::checked, checkedAttr); + if ((result == eContentAttr_HasValue) && (PR_FALSE != checkedAttr)) { + nsIRadioButton* radio; + if (NS_OK == GetWidget(aView, (nsIWidget **)&radio)) { + radio->SetState(PR_TRUE); + NS_RELEASE(radio); + } + } } // nsInputRadio +const nsString* nsInputRadio::kTYPE = new nsString("radio"); + nsInputRadio::nsInputRadio(nsIAtom* aTag, nsIFormManager* aManager) : nsInput(aTag, aManager) { + mChecked = PR_FALSE; } nsInputRadio::~nsInputRadio() { } +static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); + +void +nsInputRadioFrame::MouseClicked(nsIPresContext* aPresContext) +{ + nsIRadioButton* radioWidget; + nsIView* view; + GetView(view); + if (NS_OK == GetWidget(view, (nsIWidget **)&radioWidget)) { + radioWidget->SetState(PR_TRUE); + NS_RELEASE(radioWidget); + nsInputRadio* radio; + GetContent((nsIContent *&) radio); + nsIFormControl* control; + nsresult status = radio->QueryInterface(kIFormControlIID, (void **)&control); + NS_ASSERTION(NS_OK == status, "nsInputRadio has no nsIFormControl interface"); + if (NS_OK == status) { + radio->GetFormManager()->OnRadioChecked(*control); + NS_RELEASE(radio); + } + } + NS_RELEASE(view); +} + +PRBool +nsInputRadio::GetChecked(PRBool aGetInitialValue) const +{ + if (aGetInitialValue) { + return mChecked; + } + else { + NS_ASSERTION(mWidget, "no widget for this nsInputRadio"); + return ((nsIRadioButton *)mWidget)->GetState(); + } +} + +void +nsInputRadio::SetChecked(PRBool aValue, PRBool aSetInitialValue) +{ + if (aSetInitialValue) { + mChecked = aValue; + } + NS_ASSERTION(mWidget, "no widget for this nsInputRadio"); + ((nsIRadioButton *)mWidget)->SetState(aValue); +} + + nsIFrame* nsInputRadio::CreateFrame(nsIPresContext* aPresContext, PRInt32 aIndexInParent, @@ -114,7 +186,62 @@ void nsInputRadio::GetType(nsString& aResult) const aResult = "radio"; } -NS_HTML nsresult +void nsInputRadio::SetAttribute(nsIAtom* aAttribute, + const nsString& aValue) +{ + if (aAttribute == nsHTMLAtoms::checked) { + mChecked = PR_TRUE; + } + else { + nsInput::SetAttribute(aAttribute, aValue); + } +} + +nsContentAttr nsInputRadio::GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aResult) const +{ + aResult.Reset(); + if (aAttribute == nsHTMLAtoms::checked) { + return GetCacheAttribute(mChecked, aResult); + } + else { + return nsInput::GetAttribute(aAttribute, aResult); + } +} + +PRBool +nsInputRadio::GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues) +{ + if (aMaxNumValues <= 0) { + return PR_FALSE; + } + nsIRadioButton* radio = (nsIRadioButton *)GetWidget(); + PRBool state = radio->GetState(); + if(PR_TRUE != state) { + return PR_FALSE; + } + + if (nsnull == mValue) { + aValues[0] = "on"; + } else { + aValues[0] = *mValue; + } + aNumValues = 1; + + return PR_TRUE; +} + +void +nsInputRadio::Reset() +{ + nsIRadioButton* radio = (nsIRadioButton *)GetWidget(); + if (nsnull != radio) { + radio->SetState(mChecked); + } +} + +nsresult NS_NewHTMLInputRadio(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { @@ -131,3 +258,56 @@ NS_NewHTMLInputRadio(nsIHTMLContent** aInstancePtrResult, return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); } +// CLASS nsInputRadioGroup + +nsInputRadioGroup::nsInputRadioGroup(nsString& aName) +:mName(aName), mCheckedRadio(nsnull) +{ +} + +nsInputRadioGroup::~nsInputRadioGroup() +{ + mCheckedRadio = nsnull; +} + +PRInt32 +nsInputRadioGroup::GetRadioCount() const +{ + return mRadios.Count(); +} + +nsIFormControl* +nsInputRadioGroup::GetRadioAt(PRInt32 aIndex) const +{ + return (nsIFormControl*) mRadios.ElementAt(aIndex); +} + +PRBool +nsInputRadioGroup::AddRadio(nsIFormControl* aRadio) +{ + return mRadios.AppendElement(aRadio); +} + +PRBool +nsInputRadioGroup::RemoveRadio(nsIFormControl* aRadio) +{ + return mRadios.RemoveElement(aRadio); +} + +nsIFormControl* +nsInputRadioGroup::GetCheckedRadio() +{ + return mCheckedRadio; +} + +void +nsInputRadioGroup::SetCheckedRadio(nsIFormControl* aRadio) +{ + mCheckedRadio = aRadio; +} + +void +nsInputRadioGroup::GetName(nsString& aNameResult) const +{ + aNameResult = mName; +} diff --git a/mozilla/layout/html/forms/src/nsInputRadio.h b/mozilla/layout/html/forms/src/nsInputRadio.h index a0f2a4e1b1e..209d73b5f32 100644 --- a/mozilla/layout/html/forms/src/nsInputRadio.h +++ b/mozilla/layout/html/forms/src/nsInputRadio.h @@ -22,10 +22,12 @@ // this class defintion will be moved into nsInputRadio.cpp #include "nsInput.h" +#include "nsVoidArray.h" class nsIAtom; class nsString; -class nsInputRadio : public nsInput { +class nsInputRadio : public nsInput +{ public: nsInputRadio (nsIAtom* aTag, nsIFormManager* aManager); @@ -33,10 +35,50 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); + virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); + + virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aResult) const; + + static const nsString* kTYPE; + + virtual PRBool GetChecked(PRBool aGetInitialValue) const; + virtual void SetChecked(PRBool aValue, PRBool aSetInitialValue); + + virtual PRInt32 GetMaxNumValues() { return 1; } + + virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues); + + virtual void Reset(); + protected: virtual ~nsInputRadio(); virtual void GetType(nsString& aResult) const; + + PRBool mChecked; +}; + +class nsInputRadioGroup +{ +public: + nsInputRadioGroup(nsString& aName); + virtual ~nsInputRadioGroup(); + + PRBool AddRadio(nsIFormControl* aRadio); + PRInt32 GetRadioCount() const; + nsIFormControl* GetRadioAt(PRInt32 aIndex) const; + PRBool RemoveRadio(nsIFormControl* aRadio); + + nsIFormControl* GetCheckedRadio(); + void SetCheckedRadio(nsIFormControl* aRadio); + void GetName(nsString& aNameResult) const; + +protected: + nsString mName; + nsVoidArray mRadios; + nsIFormControl* mCheckedRadio; }; #endif diff --git a/mozilla/layout/html/forms/src/nsInputText.cpp b/mozilla/layout/html/forms/src/nsInputText.cpp index 2ce4a81a1c6..3b3ebbd6e8f 100644 --- a/mozilla/layout/html/forms/src/nsInputText.cpp +++ b/mozilla/layout/html/forms/src/nsInputText.cpp @@ -27,10 +27,12 @@ #include "nsIHTMLContent.h" #include "nsHTMLIIDs.h" #include "nsITextWidget.h" +#include "nsITextAreaWidget.h" #include "nsWidgetsCID.h" #include "nsSize.h" #include "nsString.h" #include "nsHTMLAtoms.h" +#include "nsHTMLForms.h" class nsInputTextFrame : public nsInputFrame { public: @@ -38,18 +40,24 @@ public: PRInt32 aIndexInParent, nsIFrame* aParentFrame); - virtual void PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds); + virtual nsInputWidgetData* GetWidgetInitData(); - virtual void InitializeWidget(nsIView *aView); + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); virtual const nsIID GetCID(); virtual const nsIID GetIID(); protected: + virtual ~nsInputTextFrame(); - nsString mCacheValue; + + nsInputTextType GetTextType(); + + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize); }; nsInputTextFrame::nsInputTextFrame(nsIContent* aContent, @@ -67,50 +75,117 @@ const nsIID nsInputTextFrame::GetIID() { static NS_DEFINE_IID(kTextIID, NS_ITEXTWIDGET_IID); - return kTextIID; + static NS_DEFINE_IID(kTextAreaIID, NS_ITEXTAREAWIDGET_IID); + + if (kInputTextArea == GetTextType()) { + return kTextAreaIID; + } + else { + return kTextIID; + } } const nsIID nsInputTextFrame::GetCID() { static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID); - return kTextCID; + static NS_DEFINE_IID(kTextAreaCID, NS_TEXTAREA_CID); + + if (kInputTextArea == GetTextType()) { + return kTextAreaCID; + } + else { + return kTextCID; + } +} + +nsInputTextType +nsInputTextFrame::GetTextType() +{ + nsInputText* content; + GetContent((nsIContent *&) content); + nsInputTextType type = content->GetTextType(); + NS_RELEASE(content); + return type; } void -nsInputTextFrame::PreInitializeWidget(nsIPresContext* aPresContext, - nsSize& aBounds) +nsInputTextFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize) { - nsInputText* content = (nsInputText *)mContent; // this must be an nsInputButton + // get the css size and let the frame use or override it + nsSize styleSize; + GetStyleSize(*aPresContext, aMaxSize, styleSize); - // get the value of the text - if (nsnull != content->mValue) { - mCacheValue = *content->mValue; - } else { - mCacheValue = ""; + nsSize size; + + PRBool widthExplicit, heightExplicit; + PRInt32 ignore; + if ((kInputTextText == GetTextType()) || (kInputTextPassword == GetTextType())) { + nsInputDimensionSpec textSpec(nsHTMLAtoms::size, PR_FALSE, nsHTMLAtoms::value, + 20, PR_FALSE, nsnull, 1); + CalculateSize(aPresContext, this, styleSize, textSpec, size, + widthExplicit, heightExplicit, ignore); + } + else { + nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, 10, + PR_FALSE, nsHTMLAtoms::rows, 1); + CalculateSize(aPresContext, this, styleSize, areaSpec, size, + widthExplicit, heightExplicit, ignore); + } + if (!heightExplicit && (kInputTextArea != GetTextType())) { + size.height += 100; } - float p2t = aPresContext->GetPixelsToTwips(); - aBounds.width = (int)(120 * p2t); - aBounds.height = (int)(20 * p2t); + aDesiredLayoutSize.width = size.width; + aDesiredLayoutSize.height = size.height; + aDesiredWidgetSize.width = aDesiredLayoutSize.width; + aDesiredWidgetSize.height = aDesiredLayoutSize.height; +} + +nsInputWidgetData* +nsInputTextFrame::GetWidgetInitData() +{ + static NS_DEFINE_IID(kTextIID, NS_ITEXTWIDGET_IID); + + nsInputWidgetData* data = nsnull; + nsInputText* content; + GetContent((nsIContent *&) content); + if (kInputTextPassword == content->GetTextType()) { + data = new nsInputWidgetData(); + data->arg1 = 1; + } + NS_RELEASE(content); + + return data; } void -nsInputTextFrame::InitializeWidget(nsIView *aView) +nsInputTextFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { nsITextWidget* text; if (NS_OK == GetWidget(aView, (nsIWidget **)&text)) { - text->SetText(mCacheValue); - NS_RELEASE(text); + text->SetFont(GetFont(aPresContext)); + nsInputText* content; + GetContent((nsIContent *&) content); + nsAutoString valAttr; + nsContentAttr valStatus = ((nsInput *)content)->GetAttribute(nsHTMLAtoms::value, valAttr); + text->SetText(valAttr); + NS_RELEASE(content); } } //---------------------------------------------------------------------- // nsInputText -nsInputText::nsInputText(nsIAtom* aTag, nsIFormManager* aManager) - : nsInput(aTag, aManager) +nsInputText::nsInputText(nsIAtom* aTag, nsIFormManager* aManager, nsInputTextType aType) + : nsInput(aTag, aManager), mType(aType) { + mMaxLength = CSS_NOTSET; + mNumRows = CSS_NOTSET; + mNumCols = CSS_NOTSET; } nsInputText::~nsInputText() @@ -120,14 +195,18 @@ nsInputText::~nsInputText() } } +nsInputTextType +nsInputText::GetTextType() const +{ + return mType; +} + nsIFrame* nsInputText::CreateFrame(nsIPresContext* aPresContext, PRInt32 aIndexInParent, nsIFrame* aParentFrame) { - nsIFrame* rv = new nsInputTextFrame(this, aIndexInParent, aParentFrame); - printf("** nsInputText::CreateFrame frame=%d", rv); - return rv; + return new nsInputTextFrame(this, aIndexInParent, aParentFrame); } PRInt32 @@ -165,27 +244,27 @@ nsInputText::Reset() void nsInputText::GetType(nsString& aResult) const { - aResult = "text"; + if (kInputTextText == mType) { + aResult = "text"; + } + else if (kInputTextPassword == mType) { + aResult = "password"; + } + else if (kInputTextArea == mType) { + aResult = ""; + } } void nsInputText::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) { - if (aAttribute == nsHTMLAtoms::size) { - nsHTMLValue value; - ParseValue(aValue, 1, value); - mSize = value.GetIntValue(); + if (aAttribute == nsHTMLAtoms::maxlength) { + CacheAttribute(aValue, CSS_NOTSET, mMaxLength); } - else if (aAttribute == nsHTMLAtoms::maxlength) { - nsHTMLValue value; - ParseValue(aValue, 1, value);/* XXX nav doesn't clamp; what does it do with illegal values? */ - mMaxLength = value.GetIntValue(); + else if ((aAttribute == nsHTMLAtoms::rows) && (kInputTextArea == mType)) { + CacheAttribute(aValue, CSS_NOTSET, mNumRows); } - else if (aAttribute == nsHTMLAtoms::value) { - if (nsnull == mValue) { - mValue = new nsString(aValue); - } else { - *mValue = aValue; - } + else if ((aAttribute == nsHTMLAtoms::cols) && (kInputTextArea == mType)) { + CacheAttribute(aValue, CSS_NOTSET, mNumCols); } else { nsInput::SetAttribute(aAttribute, aValue); @@ -195,33 +274,21 @@ void nsInputText::SetAttribute(nsIAtom* aAttribute, const nsString& aValue) nsContentAttr nsInputText::GetAttribute(nsIAtom* aAttribute, nsHTMLValue& aResult) const { - nsContentAttr ca = eContentAttr_NotThere; - aResult.Reset(); - if (aAttribute == nsHTMLAtoms::size) { - if (0 < mSize) { - aResult.Set(mSize, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } + if (aAttribute == nsHTMLAtoms::maxlength) { + return GetCacheAttribute(mMaxLength, aResult); + } + else if ((aAttribute == nsHTMLAtoms::rows) && (kInputTextArea == mType)) { + return GetCacheAttribute(mNumRows, aResult); } - else if (aAttribute == nsHTMLAtoms::maxlength) { - if (0 < mMaxLength) { - aResult.Set(mMaxLength, eHTMLUnit_Absolute); - ca = eContentAttr_HasValue; - } - } - else if (aAttribute == nsHTMLAtoms::value) { - if (nsnull != mValue) { - aResult.Set(*mValue); - ca = eContentAttr_HasValue; - } + else if ((aAttribute == nsHTMLAtoms::cols) && (kInputTextArea == mType)) { + return GetCacheAttribute(mNumCols, aResult); } else { - ca = nsInput::GetAttribute(aAttribute, aResult); + return nsInput::GetAttribute(aAttribute, aResult); } - return ca; } -NS_HTML nsresult +nsresult NS_NewHTMLInputText(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag, nsIFormManager* aManager) { @@ -230,7 +297,7 @@ NS_NewHTMLInputText(nsIHTMLContent** aInstancePtrResult, return NS_ERROR_NULL_POINTER; } - nsIHTMLContent* it = new nsInputText(aTag, aManager); + nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputTextText); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; @@ -238,3 +305,36 @@ NS_NewHTMLInputText(nsIHTMLContent** aInstancePtrResult, return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); } +nsresult +NS_NewHTMLInputPassword(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aManager) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + + nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputTextPassword); + + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); +} + +nsresult +NS_NewHTMLTextArea(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aManager) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + + nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputTextArea); + + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); +} diff --git a/mozilla/layout/html/forms/src/nsInputText.h b/mozilla/layout/html/forms/src/nsInputText.h index 826303a5a47..cf006328bb8 100644 --- a/mozilla/layout/html/forms/src/nsInputText.h +++ b/mozilla/layout/html/forms/src/nsInputText.h @@ -25,11 +25,17 @@ class nsIAtom; class nsString; class nsView; +enum nsInputTextType { + kInputTextText, + kInputTextPassword, + kInputTextArea +}; + // this class definition will move to nsInputText.cpp class nsInputText : public nsInput { public: - nsInputText (nsIAtom* aTag, nsIFormManager* aManager); + nsInputText (nsIAtom* aTag, nsIFormManager* aManager, nsInputTextType aType); virtual nsIFrame* CreateFrame(nsIPresContext* aPresContext, PRInt32 aIndexInParent, @@ -42,20 +48,25 @@ public: virtual PRInt32 GetMaxNumValues(); + nsInputTextType GetTextType() const; + virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues); virtual void Reset(); - // Note: this has a copy of code from nsInputFile - nsString* mValue; - PRInt32 mSize; - PRInt32 mMaxLength; - protected: + virtual ~nsInputText(); virtual void GetType(nsString& aResult) const; + + nsInputTextType mType; + + PRInt32 mMaxLength; // text, password only + PRInt32 mNumRows; // textarea only + PRInt32 mNumCols; // textarea only + }; #endif diff --git a/mozilla/layout/html/forms/src/nsSelect.cpp b/mozilla/layout/html/forms/src/nsSelect.cpp new file mode 100644 index 00000000000..906fbd9426d --- /dev/null +++ b/mozilla/layout/html/forms/src/nsSelect.cpp @@ -0,0 +1,623 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// YY need to pass isMultiple before create called + +#include "nsInputFrame.h" +#include "nsIContent.h" +#include "prtypes.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsIRadioButton.h" +#include "nsWidgetsCID.h" +#include "nsSize.h" +#include "nsHTMLAtoms.h" +#include "nsIFormManager.h" +#include "nsIView.h" +#include "nsIListWidget.h" +#include "nsIComboBox.h" +#include "nsIListBox.h" +#include "nsInput.h" + +static NS_DEFINE_IID(kListWidgetIID, NS_ILISTWIDGET_IID); +static NS_DEFINE_IID(kComboBoxIID, NS_ICOMBOBOX_IID); +static NS_DEFINE_IID(kListBoxIID, NS_ILISTBOX_IID); + + +class nsSelectFrame : public nsInputFrame { +public: + nsSelectFrame(nsIContent* aContent, + PRInt32 aIndexInParent, + nsIFrame* aParentFrame); + + virtual nsInputWidgetData* GetWidgetInitData(); + + virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView); + + virtual const nsIID GetCID(); + + virtual const nsIID GetIID(); + + PRBool IsComboBox(); + +protected: + + virtual ~nsSelectFrame(); + + virtual void GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize); +}; + +class nsSelect : public nsInput +{ +public: + nsSelect (nsIAtom* aTag, nsIFormManager* aFormMan); + + virtual nsIFrame* CreateFrame(nsIPresContext* aPresContext, + PRInt32 aIndexInParent, + nsIFrame* aParentFrame); + + virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); + + virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aResult) const; + + virtual PRInt32 GetMaxNumValues(); + + virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues); + + PRBool IsMultiple() { return mMultiple; } + + PRBool IsComboBox(); + + virtual void Reset(); + +protected: + virtual ~nsSelect(); + + virtual void GetType(nsString& aResult) const; + + PRBool mMultiple; +}; + +class nsOption : public nsInput +{ +public: + nsOption (nsIAtom* aTag); + + virtual nsIFrame* CreateFrame(nsIPresContext* aPresContext, + PRInt32 aIndexInParent, + nsIFrame* aParentFrame); + + virtual void SetAttribute(nsIAtom* aAttribute, const nsString& aValue); + + virtual nsContentAttr GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aResult) const; + + virtual PRInt32 GetMaxNumValues(); + + virtual PRBool GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues); + + PRBool GetText(nsString& aString) const; + + void SetText(nsString& aString); + +protected: + virtual ~nsOption(); + + virtual void GetType(nsString& aResult) const; + + PRBool mSelected; + nsString* mText; +}; + + +nsSelectFrame::nsSelectFrame(nsIContent* aContent, + PRInt32 aIndexInParent, + nsIFrame* aParentFrame) + : nsInputFrame(aContent, aIndexInParent, aParentFrame) +{ +} + +nsSelectFrame::~nsSelectFrame() +{ +} + +PRBool +nsSelectFrame::IsComboBox() +{ + nsSelect* content = (nsSelect *) mContent; + return content->IsComboBox(); +} + +const nsIID +nsSelectFrame::GetIID() +{ + if (IsComboBox()) { + return kComboBoxIID; + } + else { + return kListBoxIID; + } +} + +const nsIID +nsSelectFrame::GetCID() +{ + static NS_DEFINE_IID(kComboCID, NS_COMBOBOX_CID); + static NS_DEFINE_IID(kListCID, NS_LISTBOX_CID); + + if (IsComboBox()) { + return kComboCID; + } + else { + return kListCID; + } +} + +void +nsSelectFrame::GetDesiredSize(nsIPresContext* aPresContext, + const nsSize& aMaxSize, + nsReflowMetrics& aDesiredLayoutSize, + nsSize& aDesiredWidgetSize) +{ + nsSelect* select; + GetContent((nsIContent *&)select); + + // get the css size + nsSize styleSize; + GetStyleSize(*aPresContext, aMaxSize, styleSize); + + // get the size of the longest child + PRInt32 maxWidth = 1; + PRInt32 numChildren = select->ChildCount(); + for (int i = 0; i < numChildren; i++) { + nsOption* option = (nsOption*) select->ChildAt(i); // YYY this had better be an option + nsString text; + if (PR_FALSE == option->GetText(text)) { + continue; + } + nsSize textSize; + // use the style for the select rather that the option, since widgets don't support it + nsInputFrame::GetTextSize(*aPresContext, this, text, textSize); + if (textSize.width > maxWidth) { + maxWidth = textSize.width; + } + } + + PRInt32 rowHeight = 0; + nsSize calcSize, charSize; + PRBool widthExplicit, heightExplicit; + nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, maxWidth, PR_TRUE, nsHTMLAtoms::size, 1); + PRInt32 numRows = CalculateSize(aPresContext, this, styleSize, textSpec, + calcSize, widthExplicit, heightExplicit, rowHeight); + + if (!heightExplicit) { + calcSize.height += 100; + } + + PRBool isCombo = IsComboBox(); + // account for vertical scrollbar, if present + aDesiredLayoutSize.width = ((numRows < select->ChildCount()) || isCombo) + ? calcSize.width + 350 : calcSize.width + 100; + aDesiredLayoutSize.height = calcSize.height; + + aDesiredWidgetSize.width = aDesiredLayoutSize.width; + aDesiredWidgetSize.height = + (isCombo && !heightExplicit) ? rowHeight + 100 : aDesiredLayoutSize.height; + + + NS_RELEASE(select); +} + +nsInputWidgetData* +nsSelectFrame::GetWidgetInitData() +{ + nsInputWidgetData* data = nsnull; + nsSelect* content; + GetContent((nsIContent *&) content); + if (content->IsMultiple()) { + data = new nsInputWidgetData(); + data->arg1 = 1; + } + NS_RELEASE(content); + + return data; +} + +void +nsSelectFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) +{ + nsSelect* select; + GetContent((nsIContent *&)select); + + nsIView* view; + GetView(view); + + nsIListWidget* list; + nsresult stat = view->QueryInterface(kListWidgetIID, (void **) &list); + NS_ASSERTION((NS_OK == stat), "invalid widget"); + + PRBool isCombo = IsComboBox(); + PRInt32 numChildren = select->ChildCount(); + for (int i = 0; i < numChildren; i++) { + nsOption* option = (nsOption*) select->ChildAt(i); // YYY this had better be an option + nsString text; + if (PR_TRUE != option->GetText(text)) { + text = " "; + } + if (isCombo) { + printf("\n ** text = %s", text.ToNewCString()); + list->AddItemAt(text, 1); + } + else { + list->AddItemAt(text, i); + } + } + + NS_RELEASE(view); + + select->Reset(); // initializes selections +} + +// nsSelect + +nsSelect::nsSelect(nsIAtom* aTag, nsIFormManager* aFormMan) + : nsInput(aTag, aFormMan) +{ + mMultiple = PR_FALSE; +} + +nsSelect::~nsSelect() +{ +} + +void nsSelect::GetType(nsString& aResult) const +{ + aResult = "select"; +} + +nsIFrame* +nsSelect::CreateFrame(nsIPresContext* aPresContext, + PRInt32 aIndexInParent, + nsIFrame* aParentFrame) +{ + nsIFrame* rv = new nsSelectFrame(this, aIndexInParent, aParentFrame); + return rv; +} + +void nsSelect::SetAttribute(nsIAtom* aAttribute, + const nsString& aValue) +{ + if (aAttribute == nsHTMLAtoms::multiple) { + mMultiple = PR_TRUE; + } + else { + nsInput::SetAttribute(aAttribute, aValue); + } +} + +nsContentAttr nsSelect::GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aResult) const +{ + aResult.Reset(); + if (aAttribute == nsHTMLAtoms::multiple) { + return GetCacheAttribute(mMultiple, aResult); + } + else { + return nsInput::GetAttribute(aAttribute, aResult); + } +} + +PRBool +nsSelect::IsComboBox() +{ + PRBool multiple; + PRInt32 size; + + nsInput::GetAttribute(nsHTMLAtoms::size, size); + nsInput::GetAttribute(nsHTMLAtoms::multiple, multiple); + + PRBool result = (!multiple && (size <= 1)) ? PR_TRUE : PR_FALSE; + return result; +} + +PRInt32 +nsSelect::GetMaxNumValues() +{ + PRBool isMultiple; + nsInput::GetAttribute(nsHTMLAtoms::multiple, isMultiple); + + if (isMultiple) { + return ChildCount(); + } + else { + return 1; + } +} + +PRBool +nsSelect::GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, + nsString* aValues) +{ + if (aMaxNumValues <= 0) { + NS_ASSERTION(0, "invalid max num values"); + return PR_FALSE; + } + + if (!IsMultiple()) { + NS_ASSERTION(aMaxNumValues > 0, "invalid max num values"); + nsIListWidget* list; + nsresult stat = mWidget->QueryInterface(kListWidgetIID, (void **) &list); + NS_ASSERTION((NS_OK == stat), "invalid widget"); + PRInt32 index = list->GetSelectedIndex(); + if (index >= 0) { + nsOption* selected = (nsOption*)ChildAt(index); + selected->GetValues(aMaxNumValues, aNumValues, aValues); + return PR_TRUE; + } + else { + aNumValues = 0; + return PR_FALSE; + } + } + else { + nsIListBox* list; + nsresult stat = mWidget->QueryInterface(kListBoxIID, (void **) &list); + NS_ASSERTION((NS_OK == stat), "invalid widget"); + PRInt32 numSelections = list->GetSelectedCount(); + NS_ASSERTION(aMaxNumValues >= numSelections, "invalid max num values"); + if (numSelections >= 0) { + PRInt32* selections = new PRInt32[numSelections]; + list->GetSelectedIndices(selections, numSelections); + PRInt32 numValues; + aNumValues = 0; + for (int i = 0; i < numSelections; i++) { + nsOption* selected = (nsOption*)ChildAt(selections[i]); + selected->GetValues(aMaxNumValues - i, numValues, aValues + i); // options can only have 1 value + aNumValues += 1; + } + return PR_TRUE; + } + else { + aNumValues = 0; + return PR_FALSE; + } + } +} + + +void +nsSelect::Reset() +{ + PRBool allowMultiple; + nsInput::GetAttribute(nsHTMLAtoms::multiple, allowMultiple); + PRBool haveSelection = PR_FALSE; + PRInt32 numChildren = ChildCount(); + + nsIListWidget* list; + nsresult stat = mWidget->QueryInterface(kListWidgetIID, (void **) &list); + NS_ASSERTION((NS_OK == stat), "invalid widget"); + + list->Deselect(); + + for (int i = 0; i < numChildren; i++) { + nsOption* option = (nsOption*)ChildAt(i); // YYY this had better be an option + PRBool selAttr; + ((nsInput *)option)->GetAttribute(nsHTMLAtoms::selected, selAttr); + if (selAttr) { + list->SelectItem(i); + if (!allowMultiple) { + break; + } + } + } +} + + +// nsOption + +nsOption::nsOption(nsIAtom* aTag) + : nsInput(aTag, nsnull) +{ + mText = nsnull; + mSelected = PR_FALSE; +} + +nsOption::~nsOption() +{ + if (nsnull != mText) { + delete mText; + } +} + +void nsOption::GetType(nsString& aResult) const +{ + aResult = "select"; +} + +nsIFrame* +nsOption::CreateFrame(nsIPresContext* aPresContext, + PRInt32 aIndexInParent, + nsIFrame* aParentFrame) +{ + nsIFrame* frame; + nsFrame::NewFrame(&frame, this, aIndexInParent, aParentFrame); + return frame; +} + +void nsOption::SetAttribute(nsIAtom* aAttribute, + const nsString& aValue) +{ + if (aAttribute == nsHTMLAtoms::selected) { + mSelected = PR_TRUE; + } + else { + nsInput::SetAttribute(aAttribute, aValue); + } +} + +nsContentAttr nsOption::GetAttribute(nsIAtom* aAttribute, + nsHTMLValue& aResult) const +{ + aResult.Reset(); + if (aAttribute == nsHTMLAtoms::selected) { + return GetCacheAttribute(mSelected, aResult); + } + else { + return nsInput::GetAttribute(aAttribute, aResult); + } +} + +PRInt32 +nsOption::GetMaxNumValues() +{ + return 1; +} + +PRBool nsOption::GetText(nsString& aString) const +{ + if (nsnull == mText) { + return PR_FALSE; + } + else { + aString = *mText; + return PR_TRUE; + } +} + +void nsOption::SetText(nsString& aString) +{ + if (nsnull == mText) { + mText = new nsString(aString); + } + else { + *mText = aString; + } +} + +PRBool +nsOption::GetValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues) +{ + if (aMaxNumValues <= 0) { + NS_ASSERTION(aMaxNumValues > 0, "invalid max num values"); + return PR_FALSE; + } + + nsString valAttr; + nsContentAttr stat = nsInput::GetAttribute(nsHTMLAtoms::value, valAttr); + if (eContentAttr_HasValue == stat) { + aValues[0] = valAttr; + aNumValues = 1; + return PR_TRUE; + } + else if (nsnull != mText) { + aValues[0] = *mText; + aNumValues = 1; + return PR_TRUE; + } + else { + aNumValues = 0; + return PR_FALSE; + } +} + +void HACK(nsSelect* aSel, PRInt32); + +// FACTORY functions + +nsresult +NS_NewHTMLSelect(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag, nsIFormManager* aFormMan, PRInt32 aHackIndex) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + + nsIHTMLContent* it = new nsSelect(aTag, aFormMan); + + HACK((nsSelect*)it, aHackIndex); + + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); +} + +nsresult +NS_NewHTMLOption(nsIHTMLContent** aInstancePtrResult, + nsIAtom* aTag) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + + nsIHTMLContent* it = new nsOption(aTag); + + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult); +} + +void HACK(nsSelect* aSel, PRInt32 aIndex) +{ + char buf[100]; + + nsIAtom* nameAttr = NS_NewAtom("NAME"); + sprintf(&buf[0], "select %d", aIndex); + nsString name(&buf[0]); + aSel->SetAttribute(nameAttr, name); + nsIAtom* sizeAttr = NS_NewAtom("SIZE"); + int numOpt = 2; + if (aIndex == 1) { + nsString size("2"); + aSel->SetAttribute(sizeAttr, size); + } else { + nsString size("4"); + aSel->SetAttribute(sizeAttr, size); + nsIAtom* multAttr = NS_NewAtom("MULTIPLE"); + nsString mult("1"); + aSel->SetAttribute(multAttr, mult); + numOpt = 8; + } + + for (int i = 0; i < numOpt; i++) { + nsIAtom* atom = NS_NewAtom("OPTION"); + nsOption* option; + NS_NewHTMLOption((nsIHTMLContent**)&option, atom); + sprintf(&buf[0], "option %d", i); + nsString label(&buf[0]); + option->SetText(label); + aSel->AppendChild(option); + } +} + + + + diff --git a/mozilla/string/obsolete/nsString.cpp b/mozilla/string/obsolete/nsString.cpp index e3dd9f715ba..a4c6b86e46a 100644 --- a/mozilla/string/obsolete/nsString.cpp +++ b/mozilla/string/obsolete/nsString.cpp @@ -538,6 +538,7 @@ float nsString::ToFloat(PRInt32* aErrorCode) const if (*cp != 0) { *aErrorCode = NS_ERROR_ILLEGAL_VALUE; } + *aErrorCode = NS_OK; return f; } @@ -588,6 +589,7 @@ PRInt32 nsString::ToInteger(PRInt32* aErrorCode) const { if (sign == '-') { rv = -rv; } + *aErrorCode = NS_OK; return rv; } diff --git a/mozilla/view/public/nsIView.h b/mozilla/view/public/nsIView.h index 6fb9ba7b6b8..60562cad3a2 100644 --- a/mozilla/view/public/nsIView.h +++ b/mozilla/view/public/nsIView.h @@ -66,6 +66,8 @@ public: * @param aWindowIID IID for Widget type that this view * should have associated with it. if nsull, then no * width will be created for this view + * @param aWidgetInitData data used to initialize this view's widget before + * its create is called. * @param aNative native window that will be used as parent of * aWindowIID. if nsnull, then parent will be derived from * parent view and it's ancestors @@ -79,6 +81,7 @@ public: const nsRect &aBounds, nsIView *aParent, const nsIID *aWindowIID = nsnull, + void *aWidgetInitData = nsnull, nsNativeWindow aNative = nsnull, PRInt32 aZIndex = 0, const nsRect *aClipRect = nsnull, diff --git a/mozilla/view/src/nsScrollingView.cpp b/mozilla/view/src/nsScrollingView.cpp index f5ee0ce8ba2..cd7c79709ec 100644 --- a/mozilla/view/src/nsScrollingView.cpp +++ b/mozilla/view/src/nsScrollingView.cpp @@ -116,6 +116,7 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager, const nsRect &aBounds, nsIView *aParent, const nsIID *aWindowIID, + void *aWidgetInitData, nsNativeWindow aNative, PRInt32 aZIndex, const nsRect *aClipRect, @@ -124,7 +125,7 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager, { nsresult rv; - rv = nsView :: Init(aManager, aBounds, aParent, aWindowIID, aNative, aZIndex, aClipRect, aOpacity, aVisibilityFlag); + rv = nsView :: Init(aManager, aBounds, aParent, aWindowIID, aWidgetInitData, aNative, aZIndex, aClipRect, aOpacity, aVisibilityFlag); if (rv == NS_OK) { diff --git a/mozilla/view/src/nsScrollingView.h b/mozilla/view/src/nsScrollingView.h index cdb2178bb70..da40fac05b6 100644 --- a/mozilla/view/src/nsScrollingView.h +++ b/mozilla/view/src/nsScrollingView.h @@ -40,6 +40,7 @@ public: const nsRect &aBounds, nsIView *aParent, const nsIID *aWindowIID = nsnull, + void *aWidgetInitData = nsnull, nsNativeWindow aNative = nsnull, PRInt32 aZIndex = 0, const nsRect *aClipRect = nsnull, diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index bc16fb4603c..8eb239a1eaf 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -246,12 +246,14 @@ nsresult nsView :: Init(nsIViewManager* aManager, const nsRect &aBounds, nsIView *aParent, const nsCID *aWindowCIID, + void *aWidgetInitData, nsNativeWindow aNative, PRInt32 aZIndex, const nsRect *aClipRect, float aOpacity, nsViewVisibility aVisibilityFlag) { + //printf(" \n callback=%d data=%d", aWidgetCreateCallback, aCallbackData); NS_PRECONDITION(nsnull != aManager, "null ptr"); if (nsnull == aManager) { return NS_ERROR_NULL_POINTER; @@ -277,14 +279,15 @@ nsresult nsView :: Init(nsIViewManager* aManager, trect *= cx->GetTwipsToPixels(); + static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); if (NS_OK == LoadWidget(*aWindowCIID)) { if (aNative) - mWindow->Create(aNative, trect, ::HandleEvent, dx); + mWindow->Create(aNative, trect, ::HandleEvent, dx, nsnull, aWidgetInitData); else { nsIWidget *parent = GetWindowTemp(aParent); - mWindow->Create(parent, trect, ::HandleEvent, dx); + mWindow->Create(parent, trect, ::HandleEvent, dx, nsnull, aWidgetInitData); NS_IF_RELEASE(parent); } } diff --git a/mozilla/view/src/nsView.h b/mozilla/view/src/nsView.h index 365052a7978..491aa240ecd 100644 --- a/mozilla/view/src/nsView.h +++ b/mozilla/view/src/nsView.h @@ -46,11 +46,13 @@ public: const nsRect &aBounds, nsIView *aParent, const nsCID *aWindowIID = nsnull, + void *aWidgetInitData = nsnull, nsNativeWindow aNative = nsnull, PRInt32 aZIndex = 0, const nsRect *aClipRect = nsnull, float aOpacity = 1.0f, nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow); + virtual void Destroy(); virtual nsIViewManager * GetViewManager(); virtual nsIWidget * GetWidget(); diff --git a/mozilla/webshell/src/nsWebWidget.cpp b/mozilla/webshell/src/nsWebWidget.cpp index 83e3d6804eb..d3deba884ec 100644 --- a/mozilla/webshell/src/nsWebWidget.cpp +++ b/mozilla/webshell/src/nsWebWidget.cpp @@ -205,6 +205,7 @@ nsresult WebWidgetImpl::MakeWindow(nsNativeWindow aNativeParent, tbounds, nsnull, &kWidgetCID, + nsnull, aNativeParent))) { return rv; } diff --git a/mozilla/webshell/tests/viewer/samples/test8.html b/mozilla/webshell/tests/viewer/samples/test8.html index c173ee57c3a..95d5249e4e1 100644 --- a/mozilla/webshell/tests/viewer/samples/test8.html +++ b/mozilla/webshell/tests/viewer/samples/test8.html @@ -2,36 +2,35 @@ Example 8 -

Example 8: Simple Forms

+

Example 8: Form Controls

-
+ -A checkbox:
+
+a text field +
+ +
+a text area +
+ +
+a checkbox:
+
+

radio buttons

+
+ radio1 + radio2 +
+select/option hack1 + +
+select/option hack2 + +

+ + -Another checkbox:
- -Yet another checkbox:
- -One last checkbox:
- -

This is a simple form

-

This is a simple form

-

This is a simple form

-

This is a simple form

-

This is a simple form

-

-

enter some text

-

-

-

-

" " - -

-

This is a simple form

-

This is a simple form

-

This is a simple form

-

This is a simple form

-

This is a simple form

diff --git a/mozilla/widget/public/nsIFileWidget.h b/mozilla/widget/public/nsIFileWidget.h index d4f56dbec95..37b1d01e75f 100644 --- a/mozilla/widget/public/nsIFileWidget.h +++ b/mozilla/widget/public/nsIFileWidget.h @@ -53,13 +53,15 @@ public: * @param aMode the mode of the widget * @param aContext context for displaying widget * @param aToolkit toolkit associated with file widget + * @param aInitData data that is used for widget initialization */ virtual void Create( nsIWidget *aParent, nsString& aTitle, nsMode aMode, nsIDeviceContext *aContext = nsnull, - nsIToolkit *aToolkit = nsnull) = 0; + nsIToolkit *aToolkit = nsnull, + void *aInitData = 0) = 0; /** * Set the list of file filters diff --git a/mozilla/widget/public/nsIWidget.h b/mozilla/widget/public/nsIWidget.h index a6007e49ec8..2a7fd7108bc 100644 --- a/mozilla/widget/public/nsIWidget.h +++ b/mozilla/widget/public/nsIWidget.h @@ -117,12 +117,15 @@ class nsIWidget : public nsISupports { * @param parent or null if it's a top level window * @param aRect the widget dimension * @param aHandleEventFunction the event handler callback function + * @param aInitData data that is used for widget initialization + * */ virtual void Create(nsIWidget *aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, - nsIToolkit *aToolkit = nsnull) = 0; + nsIToolkit *aToolkit = nsnull, + void *aInitData = nsnull) = 0; /** * Create and initialize a widget with a native window parent @@ -147,7 +150,8 @@ class nsIWidget : public nsISupports { const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, - nsIToolkit *aToolkit = nsnull) = 0; + nsIToolkit *aToolkit = nsnull, + void *aInitData = nsnull) = 0; /** * Close and destroy the internal native window. diff --git a/mozilla/widget/src/windows/nsComboBox.cpp b/mozilla/widget/src/windows/nsComboBox.cpp index eb4ecd47525..7bc1fbcf6ca 100644 --- a/mozilla/widget/src/windows/nsComboBox.cpp +++ b/mozilla/widget/src/windows/nsComboBox.cpp @@ -164,10 +164,18 @@ nsresult nsComboBox::QueryObject(const nsIID& aIID, void** aInstancePtr) nsresult result = nsWindow::QueryObject(aIID, aInstancePtr); static NS_DEFINE_IID(kInsComboBoxIID, NS_ICOMBOBOX_IID); - if (result == NS_NOINTERFACE && aIID.Equals(kInsComboBoxIID)) { + static NS_DEFINE_IID(kInsListWidgetIID, NS_ILISTWIDGET_IID); + if (result == NS_NOINTERFACE) { + if (aIID.Equals(kInsComboBoxIID)) { *aInstancePtr = (void*) ((nsIComboBox*)this); AddRef(); result = NS_OK; + } + else if (aIID.Equals(kInsListWidgetIID)) { + *aInstancePtr = (void*) ((nsIListWidget*)this); + AddRef(); + result = NS_OK; + } } return result; diff --git a/mozilla/widget/src/windows/nsFileWidget.cpp b/mozilla/widget/src/windows/nsFileWidget.cpp index 9b1c41dc3a0..faf27f15d2c 100644 --- a/mozilla/widget/src/windows/nsFileWidget.cpp +++ b/mozilla/widget/src/windows/nsFileWidget.cpp @@ -144,7 +144,8 @@ void nsFileWidget:: Create(nsIWidget *aParent, nsString& aTitle, nsMode aMode, nsIDeviceContext *aContext, - nsIToolkit *aToolkit) + nsIToolkit *aToolkit, + void *aInitData) { mWnd = aParent; mTitle.SetLength(0); diff --git a/mozilla/widget/src/windows/nsFileWidget.h b/mozilla/widget/src/windows/nsFileWidget.h index c46365c5dc3..09dcfe535bd 100644 --- a/mozilla/widget/src/windows/nsFileWidget.h +++ b/mozilla/widget/src/windows/nsFileWidget.h @@ -46,7 +46,8 @@ class nsFileWidget : public nsIFileWidget, public nsObject nsString& aTitle, nsMode aMode, nsIDeviceContext *aContext = nsnull, - nsIToolkit *aToolkit = nsnull); + nsIToolkit *aToolkit = nsnull, + void *aInitData = nsnull); // nsIFileWidget part virtual PRBool Show(); diff --git a/mozilla/widget/src/windows/nsListBox.cpp b/mozilla/widget/src/windows/nsListBox.cpp index 8a930471b85..7419d01669e 100644 --- a/mozilla/widget/src/windows/nsListBox.cpp +++ b/mozilla/widget/src/windows/nsListBox.cpp @@ -35,6 +35,14 @@ void nsListBox::SetMultipleSelection(PRBool aMultipleSelections) mMultiSelect = aMultipleSelections; } +void nsListBox::PreCreateWidget(void *aInitData) +{ + if (nsnull != aInitData) { + nsWidgetInitData* data = (nsWidgetInitData *) aInitData; + mMultiSelect = (0 == data->arg1) ? PR_FALSE : PR_TRUE; + } +} + //------------------------------------------------------------------------- // // destructor @@ -216,10 +224,18 @@ nsresult nsListBox::QueryObject(const nsIID& aIID, void** aInstancePtr) nsresult result = nsWindow::QueryObject(aIID, aInstancePtr); static NS_DEFINE_IID(kInsListBoxIID, NS_ILISTBOX_IID); - if (result == NS_NOINTERFACE && aIID.Equals(kInsListBoxIID)) { + static NS_DEFINE_IID(kInsListWidgetIID, NS_ILISTWIDGET_IID); + if (result == NS_NOINTERFACE) { + if (aIID.Equals(kInsListBoxIID)) { *aInstancePtr = (void*) ((nsIListBox*)this); AddRef(); result = NS_OK; + } + else if (aIID.Equals(kInsListWidgetIID)) { + *aInstancePtr = (void*) ((nsIListWidget*)this); + AddRef(); + result = NS_OK; + } } return result; diff --git a/mozilla/widget/src/windows/nsListBox.h b/mozilla/widget/src/windows/nsListBox.h index fd74045f727..564e2241bbd 100644 --- a/mozilla/widget/src/windows/nsListBox.h +++ b/mozilla/widget/src/windows/nsListBox.h @@ -60,7 +60,7 @@ public: void GetSelectedIndices(PRInt32 aIndices[], PRInt32 aSize); void SelectItem(PRInt32 aPosition); void Deselect() ; - + virtual void PreCreateWidget(void *aInitData); protected: PRBool mMultiSelect; virtual LPCTSTR WindowClass(); diff --git a/mozilla/widget/src/windows/nsRadioButton.cpp b/mozilla/widget/src/windows/nsRadioButton.cpp index 74cce3a7bc0..9c2d038efff 100644 --- a/mozilla/widget/src/windows/nsRadioButton.cpp +++ b/mozilla/widget/src/windows/nsRadioButton.cpp @@ -159,23 +159,6 @@ void nsRadioButton::GetLabel(nsString& aBuffer) NS_FREE_CHAR_BUF(label); } -//------------------------------------------------------------------------- -// -// Process all windows messages -// -//------------------------------------------------------------------------- -PRBool nsRadioButton::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *aRetValue) -{ - *aRetValue = 0; - - if (msg == WM_LBUTTONUP) { - SetState(PR_TRUE); - return PR_FALSE; - } else { - return nsWindow::ProcessMessage(msg, wParam, lParam, aRetValue); - } -} - //------------------------------------------------------------------------- // // paint message. Don't send the paint out diff --git a/mozilla/widget/src/windows/nsRadioButton.h b/mozilla/widget/src/windows/nsRadioButton.h index b851ad36fac..610975f353d 100644 --- a/mozilla/widget/src/windows/nsRadioButton.h +++ b/mozilla/widget/src/windows/nsRadioButton.h @@ -70,8 +70,6 @@ protected: virtual DWORD WindowStyle(); virtual DWORD WindowExStyle(); - virtual PRBool ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *aRetValue); - }; #endif // nsRadioButton_h__ diff --git a/mozilla/widget/src/windows/nsTextAreaWidget.cpp b/mozilla/widget/src/windows/nsTextAreaWidget.cpp index 61f8fbdf40d..442ef17c221 100644 --- a/mozilla/widget/src/windows/nsTextAreaWidget.cpp +++ b/mozilla/widget/src/windows/nsTextAreaWidget.cpp @@ -143,7 +143,8 @@ LPCTSTR nsTextAreaWidget::WindowClass() DWORD nsTextAreaWidget::WindowStyle() { DWORD style = nsTextHelper::WindowStyle(); - style = style | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL; + //style = style | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL; + style = style | ES_MULTILINE | ES_WANTRETURN | WS_HSCROLL | WS_VSCROLL; return style; } diff --git a/mozilla/widget/src/windows/nsTextHelper.cpp b/mozilla/widget/src/windows/nsTextHelper.cpp index 9866595fe16..0dbe33aba2a 100644 --- a/mozilla/widget/src/windows/nsTextHelper.cpp +++ b/mozilla/widget/src/windows/nsTextHelper.cpp @@ -25,12 +25,19 @@ #include +void nsTextHelper::PreCreateWidget(void *aInitData) +{ + if (nsnull != aInitData) { + nsWidgetInitData* data = (nsWidgetInitData *) aInitData; + mIsPassword = (0 == data->arg1) ? PR_FALSE : PR_TRUE; + } +} + void nsTextHelper::SetMaxTextLength(PRUint32 aChars) { ::SendMessage(mWnd, EM_SETLIMITTEXT, (WPARAM) (INT)aChars, 0); } - PRUint32 nsTextHelper::GetText(nsString& aTextBuffer, PRUint32 aBufferSize) { int length = GetWindowTextLength(mWnd); diff --git a/mozilla/widget/src/windows/nsTextHelper.h b/mozilla/widget/src/windows/nsTextHelper.h index 99d968e5aaa..eb380dddc60 100644 --- a/mozilla/widget/src/windows/nsTextHelper.h +++ b/mozilla/widget/src/windows/nsTextHelper.h @@ -47,6 +47,8 @@ public: virtual LPCTSTR WindowClass(); virtual DWORD WindowStyle(); + virtual void PreCreateWidget(void *aInitData); + protected: PRBool mIsPassword; diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index fa2471f113c..9a58f1c51e2 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -162,7 +162,8 @@ void nsWindow::Create(nsIWidget *aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, - nsIToolkit *aToolkit) + nsIToolkit *aToolkit, + void *aInitData) { if (NULL == mToolkit) { if (NULL != aToolkit) { @@ -195,7 +196,8 @@ void nsWindow::Create(nsIWidget *aParent, args[2] = (DWORD)aHandleEventFunction; args[3] = (DWORD)aContext; args[4] = (DWORD)aToolkit; - MethodInfo info(this, nsWindow::CREATE, 5, args); + args[5] = (DWORD)aInitData; + MethodInfo info(this, nsWindow::CREATE, 6, args); mToolkit->CallMethod(&info); return; } @@ -220,6 +222,10 @@ void nsWindow::Create(nsIWidget *aParent, mContext->Init(); } + if (nsnull != aInitData) { + PreCreateWidget(aInitData); + } + mWnd = ::CreateWindowEx(WindowExStyle(), WindowClass(), "", @@ -279,7 +285,8 @@ void nsWindow::Create(nsNativeWindow aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, - nsIToolkit *aToolkit) + nsIToolkit *aToolkit, + void *aInitData) { if (NULL == mToolkit) { @@ -306,6 +313,7 @@ void nsWindow::Create(nsNativeWindow aParent, args[2] = (DWORD)aHandleEventFunction; args[3] = (DWORD)aContext; args[4] = (DWORD)aToolkit; + args[5] = (DWORD)aInitData; MethodInfo info(this, nsWindow::CREATE_NATIVE, 5, args); mToolkit->CallMethod(&info); return; @@ -331,6 +339,10 @@ void nsWindow::Create(nsNativeWindow aParent, mContext->Init(); } + if (nsnull != aInitData) { + PreCreateWidget(aInitData); + } + mWnd = ::CreateWindowEx(WindowExStyle(), WindowClass(), "", @@ -898,21 +910,23 @@ BOOL nsWindow::CallMethod(MethodInfo *info) switch (info->methodId) { case nsWindow::CREATE: - NS_ASSERTION(info->nArgs == 5, "Wrong number of arguments to CallMethod"); + NS_ASSERTION(info->nArgs == 6, "Wrong number of arguments to CallMethod"); Create((nsIWidget*)(info->args[0]), (nsRect&)*(nsRect*)(info->args[1]), (EVENT_CALLBACK)(info->args[2]), (nsIDeviceContext*)(info->args[3]), - (nsIToolkit*)(info->args[4])); + (nsIToolkit*)(info->args[4]), + (void*)(info->args[5])); break; case nsWindow::CREATE_NATIVE: - NS_ASSERTION(info->nArgs == 5, "Wrong number of arguments to CallMethod"); + NS_ASSERTION(info->nArgs == 6, "Wrong number of arguments to CallMethod"); Create((nsNativeWindow)(info->args[0]), (nsRect&)*(nsRect*)(info->args[1]), (EVENT_CALLBACK)(info->args[2]), (nsIDeviceContext*)(info->args[3]), - (nsIToolkit*)(info->args[4])); + (nsIToolkit*)(info->args[4]), + (void*)(info->args[5])); return TRUE; case nsWindow::DESTROY: diff --git a/mozilla/widget/src/windows/nsWindow.h b/mozilla/widget/src/windows/nsWindow.h index 2b327763a84..9863a62cbfe 100644 --- a/mozilla/widget/src/windows/nsWindow.h +++ b/mozilla/widget/src/windows/nsWindow.h @@ -36,6 +36,14 @@ RGB(NS_GET_R(color),NS_GET_G(color),NS_GET_B(color)) +// data passed in and used before the widget's create method is called +struct nsWidgetInitData { + DWORD arg1; + DWORD arg2; + DWORD arg3; + DWORD arg4; +}; + /** * Native WIN32 window wrapper. */ @@ -54,17 +62,20 @@ public: virtual nsresult QueryObject(const nsIID& aIID, void** aInstancePtr); + virtual void PreCreateWidget(void *aWidgetInitData) {} // nsIWidget interface virtual void Create(nsIWidget *aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, - nsIToolkit *aToolkit = nsnull); + nsIToolkit *aToolkit = nsnull, + void *aInitData = nsnull); virtual void Create(nsNativeWindow aParent, const nsRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsIDeviceContext *aContext, - nsIToolkit *aToolkit = nsnull); + nsIToolkit *aToolkit = nsnull, + void *aInitData = nsnull); virtual void Destroy(); virtual nsIWidget* GetParent(void); virtual nsIEnumerator* GetChildren(); @@ -220,9 +231,10 @@ protected: const nsRect &aRect, \ EVENT_CALLBACK aHandleEventFunction, \ nsIDeviceContext *aContext, \ - nsIToolkit *aToolkit = nsnull) \ + nsIToolkit *aToolkit = nsnull, \ + void *aInitData = nsnull) \ { \ - nsWindow::Create(aParent, aRect, aHandleEventFunction, aContext, aToolkit); \ + nsWindow::Create(aParent, aRect, aHandleEventFunction, aContext, aToolkit, aInitData); \ } \ #define BASE_WINDOWS_METHODS \ @@ -230,9 +242,10 @@ protected: const nsRect &aRect, \ EVENT_CALLBACK aHandleEventFunction, \ nsIDeviceContext *aContext, \ - nsIToolkit *aToolkit = nsnull) \ + nsIToolkit *aToolkit = nsnull, \ + void *aInitData = nsnull) \ { \ - nsWindow::Create(aParent, aRect, aHandleEventFunction, aContext, aToolkit); \ + nsWindow::Create(aParent, aRect, aHandleEventFunction, aContext, aToolkit, aInitData); \ } \ void Destroy(void) \ { \ diff --git a/mozilla/xpcom/ds/nsString.cpp b/mozilla/xpcom/ds/nsString.cpp index e3dd9f715ba..a4c6b86e46a 100644 --- a/mozilla/xpcom/ds/nsString.cpp +++ b/mozilla/xpcom/ds/nsString.cpp @@ -538,6 +538,7 @@ float nsString::ToFloat(PRInt32* aErrorCode) const if (*cp != 0) { *aErrorCode = NS_ERROR_ILLEGAL_VALUE; } + *aErrorCode = NS_OK; return f; } @@ -588,6 +589,7 @@ PRInt32 nsString::ToInteger(PRInt32* aErrorCode) const { if (sign == '-') { rv = -rv; } + *aErrorCode = NS_OK; return rv; } diff --git a/mozilla/xpcom/string/obsolete/nsString.cpp b/mozilla/xpcom/string/obsolete/nsString.cpp index e3dd9f715ba..a4c6b86e46a 100644 --- a/mozilla/xpcom/string/obsolete/nsString.cpp +++ b/mozilla/xpcom/string/obsolete/nsString.cpp @@ -538,6 +538,7 @@ float nsString::ToFloat(PRInt32* aErrorCode) const if (*cp != 0) { *aErrorCode = NS_ERROR_ILLEGAL_VALUE; } + *aErrorCode = NS_OK; return f; } @@ -588,6 +589,7 @@ PRInt32 nsString::ToInteger(PRInt32* aErrorCode) const { if (sign == '-') { rv = -rv; } + *aErrorCode = NS_OK; return rv; }