diff --git a/mozilla/content/html/content/public/nsIFormControl.h b/mozilla/content/html/content/public/nsIFormControl.h index d46896ebab8..2c5a1b4b6df 100644 --- a/mozilla/content/html/content/public/nsIFormControl.h +++ b/mozilla/content/html/content/public/nsIFormControl.h @@ -37,11 +37,12 @@ class nsIWidget; #define NS_FORM_INPUT_RADIO 12 #define NS_FORM_INPUT_SUBMIT 13 #define NS_FORM_INPUT_TEXT 14 -#define NS_FORM_OPTION 15 -#define NS_FORM_OPTGROUP 16 -#define NS_FORM_LEGEND 17 -#define NS_FORM_SELECT 18 -#define NS_FORM_TEXTAREA 19 +#define NS_FORM_LABEL 15 +#define NS_FORM_OPTION 16 +#define NS_FORM_OPTGROUP 17 +#define NS_FORM_LEGEND 18 +#define NS_FORM_SELECT 19 +#define NS_FORM_TEXTAREA 20 #define NS_FORM_NOTOK 0xFFFFFFF7 #define NS_FORM_NOTSET 0xFFFFFFF7 diff --git a/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp b/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp index b7ba9507699..047abe1a3eb 100644 --- a/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLFieldSetElement.cpp @@ -39,7 +39,7 @@ class nsHTMLFieldSetElement : public nsIDOMHTMLFieldSetElement, public nsIScriptObjectOwner, public nsIDOMEventReceiver, public nsIHTMLContent, - public nsIFormControl + public nsIFormControl { public: nsHTMLFieldSetElement(nsIAtom* aTag); diff --git a/mozilla/content/html/content/src/nsHTMLFormElement.cpp b/mozilla/content/html/content/src/nsHTMLFormElement.cpp index 9c8b9a0e0e6..f93da052552 100644 --- a/mozilla/content/html/content/src/nsHTMLFormElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLFormElement.cpp @@ -161,7 +161,7 @@ nsHTMLFormElement::nsHTMLFormElement(nsIAtom* aTag) mInner.Init(this, aTag); mControls = new nsFormControlList(); NS_ADDREF(mControls); -nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__); +//nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__); } nsHTMLFormElement::~nsHTMLFormElement() @@ -180,10 +180,7 @@ nsHTMLFormElement::~nsHTMLFormElement() NS_RELEASE(mControls); - // XXX make sure this gets moved into nsFormFrame, but not the 1st one!! - //mChildren.Clear(); - //RemoveRadioGroups(); -nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__); +//nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__); } // nsISupports @@ -212,7 +209,7 @@ nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_IMETHODIMP nsHTMLFormElement::AddRef(void) { -nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__); +//nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__); PRInt32 refCnt = mRefCnt; // debugging return ++mRefCnt; } @@ -220,7 +217,7 @@ nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__); NS_IMETHODIMP_(nsrefcnt) nsHTMLFormElement::Release() { -nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__); +//nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__); --mRefCnt; PRUint32 numChildren; GetElementCount(&numChildren); @@ -480,6 +477,7 @@ nsFormControlList::nsFormControlList() nsFormControlList::~nsFormControlList() { + Clear(); } NS_IMETHODIMP diff --git a/mozilla/content/html/content/src/nsHTMLInputElement.cpp b/mozilla/content/html/content/src/nsHTMLInputElement.cpp index f0d6b6cb78e..e134db9068f 100644 --- a/mozilla/content/html/content/src/nsHTMLInputElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLInputElement.cpp @@ -151,7 +151,7 @@ nsHTMLInputElement::nsHTMLInputElement(nsIAtom* aTag) mType = NS_FORM_INPUT_TEXT; // default value mForm = nsnull; mWidget = nsnull; - //nsTraceRefcnt::Create((nsIFormControl*)this, "nsHTMLFormControlElement", __FILE__, __LINE__); + nsTraceRefcnt::Create((nsIFormControl*)this, "nsHTMLFormControlElement", __FILE__, __LINE__); } nsHTMLInputElement::~nsHTMLInputElement() @@ -162,7 +162,7 @@ nsHTMLInputElement::~nsHTMLInputElement() mForm->RemoveElement(this, PR_FALSE); NS_RELEASE(mForm); } - //nsTraceRefcnt::Destroy((nsIFormControl*)this, __FILE__, __LINE__); + nsTraceRefcnt::Destroy((nsIFormControl*)this, __FILE__, __LINE__); } // nsISupports @@ -170,7 +170,7 @@ nsHTMLInputElement::~nsHTMLInputElement() NS_IMETHODIMP_(nsrefcnt) nsHTMLInputElement::AddRef(void) { - //nsTraceRefcnt::AddRef((nsIFormControl*)this, mRefCnt+1, __FILE__, __LINE__); + nsTraceRefcnt::AddRef((nsIFormControl*)this, mRefCnt+1, __FILE__, __LINE__); PRInt32 refCnt = mRefCnt; // debugging return ++mRefCnt; } @@ -196,7 +196,7 @@ nsHTMLInputElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_IMETHODIMP_(nsrefcnt) nsHTMLInputElement::Release() { - //nsTraceRefcnt::Release((nsIFormControl*)this, mRefCnt-1, __FILE__, __LINE__); + nsTraceRefcnt::Release((nsIFormControl*)this, mRefCnt-1, __FILE__, __LINE__); --mRefCnt; if (mRefCnt <= 0) { delete this; diff --git a/mozilla/content/html/content/src/nsHTMLLabelElement.cpp b/mozilla/content/html/content/src/nsHTMLLabelElement.cpp index ac8a11f181f..7f4fc31d57f 100644 --- a/mozilla/content/html/content/src/nsHTMLLabelElement.cpp +++ b/mozilla/content/html/content/src/nsHTMLLabelElement.cpp @@ -17,6 +17,7 @@ * Netscape Communications Corporation. All Rights Reserved. */ #include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLFormElement.h" #include "nsIScriptObjectOwner.h" #include "nsIDOMEventReceiver.h" #include "nsIHTMLContent.h" @@ -26,13 +27,20 @@ #include "nsIStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" +#include "nsIFormControl.h" +#include "nsIForm.h" static NS_DEFINE_IID(kIDOMHTMLLabelElementIID, NS_IDOMHTMLLABELELEMENT_IID); +static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID); +static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID); +static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); class nsHTMLLabelElement : public nsIDOMHTMLLabelElement, public nsIScriptObjectOwner, public nsIDOMEventReceiver, - public nsIHTMLContent + public nsIHTMLContent, + public nsIFormControl + { public: nsHTMLLabelElement(nsIAtom* aTag); @@ -52,6 +60,7 @@ public: // nsIDOMHTMLLabelElement NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm); + NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm); NS_IMETHOD GetAccessKey(nsString& aAccessKey); NS_IMETHOD SetAccessKey(const nsString& aAccessKey); NS_IMETHOD GetHtmlFor(nsString& aHtmlFor); @@ -69,10 +78,17 @@ public: // nsIHTMLContent NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner) + // nsIFormControl + NS_IMETHOD GetType(PRInt32* aType) { return NS_FORM_LABEL; } + NS_IMETHOD SetWidget(nsIWidget* aWidget) { return NS_OK; } + NS_IMETHOD Init() { return NS_OK; } + protected: nsGenericHTMLContainerElement mInner; + nsIForm* mForm; }; +// construction, destruction nsresult NS_NewHTMLLabelElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag) { @@ -91,29 +107,57 @@ nsHTMLLabelElement::nsHTMLLabelElement(nsIAtom* aTag) { NS_INIT_REFCNT(); mInner.Init(this, aTag); + mForm = nsnull; } nsHTMLLabelElement::~nsHTMLLabelElement() { + if (nsnull != mForm) { + // prevent mForm from decrementing its ref count on us + mForm->RemoveElement(this, PR_FALSE); + NS_RELEASE(mForm); + } } +// nsISupports + NS_IMPL_ADDREF(nsHTMLLabelElement) -NS_IMPL_RELEASE(nsHTMLLabelElement) +NS_IMETHODIMP_(nsrefcnt) +nsHTMLLabelElement::Release() +{ + --mRefCnt; + if (mRefCnt <= 0) { + delete this; + return 0; + } else if ((1 == mRefCnt) && mForm) { + mRefCnt = 0; + delete this; + return 0; + } else { + return mRefCnt; + } +} nsresult nsHTMLLabelElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) { NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this) if (aIID.Equals(kIDOMHTMLLabelElementIID)) { - nsIDOMHTMLLabelElement* tmp = this; - *aInstancePtr = (void*) tmp; - mRefCnt++; + *aInstancePtr = (void*)(nsIDOMHTMLLabelElement*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + else if (aIID.Equals(kIFormControlIID)) { + *aInstancePtr = (void*)(nsIFormControl*) this; + NS_ADDREF_THIS(); return NS_OK; } return NS_NOINTERFACE; } +// nsIDOMHTMLLabelElement + nsresult nsHTMLLabelElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) { @@ -128,19 +172,67 @@ nsHTMLLabelElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) NS_IMETHODIMP nsHTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm) { - *aForm = nsnull;/* XXX */ - return NS_OK; + nsresult result = NS_OK; + *aForm = nsnull; + if (nsnull != mForm) { + nsIDOMHTMLFormElement* formElem = nsnull; + result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem); + if (NS_OK == result) { + *aForm = formElem; + } + } + return result; +} + +// An important assumption is that if aForm is null, the previous mForm will not be released +// This allows nsHTMLFormElement to deal with circular references. +NS_IMETHODIMP +nsHTMLLabelElement::SetForm(nsIDOMHTMLFormElement* aForm) +{ + nsresult result = NS_OK; + if (nsnull == aForm) { + mForm = nsnull; + return NS_OK; + } else { + NS_IF_RELEASE(mForm); + nsIFormControl* formControl = nsnull; + result = QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && formControl) { + result = aForm->QueryInterface(kIFormIID, (void**)&mForm); // keep the ref + if ((NS_OK == result) && mForm) { + mForm->AddElement(formControl); + } + NS_RELEASE(formControl); + } + } + return result; } NS_IMPL_STRING_ATTR(nsHTMLLabelElement, AccessKey, accesskey, eSetAttrNotify_None) -NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for, eSetAttrNotify_None) +//NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for, eSetAttrNotify_None) + +NS_IMETHODIMP +nsHTMLLabelElement::GetHtmlFor(nsString& aValue) +{ + mInner.GetAttribute(nsHTMLAtoms::_for, aValue); + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLLabelElement::SetHtmlFor(const nsString& aValue) +{ + // trim leading and trailing whitespace + static char whitespace[] = " \r\n\t"; + nsString value(aValue); + value.Trim(whitespace, PR_TRUE, PR_TRUE); + return mInner.SetAttribute(nsHTMLAtoms::defaultvalue, value, PR_TRUE); +} NS_IMETHODIMP nsHTMLLabelElement::StringToAttribute(nsIAtom* aAttribute, const nsString& aValue, nsHTMLValue& aResult) { - // XXX write me return NS_CONTENT_ATTR_NOT_THERE; } @@ -149,7 +241,6 @@ nsHTMLLabelElement::AttributeToString(nsIAtom* aAttribute, nsHTMLValue& aValue, nsString& aResult) const { - // XXX write me return mInner.AttributeToString(aAttribute, aValue, aResult); } @@ -158,7 +249,6 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes, nsIStyleContext* aContext, nsIPresContext* aPresContext) { - // XXX write me nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext); } @@ -179,3 +269,4 @@ nsHTMLLabelElement::HandleDOMEvent(nsIPresContext& aPresContext, return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); } + diff --git a/mozilla/content/html/document/src/nsHTMLContentSink.cpp b/mozilla/content/html/document/src/nsHTMLContentSink.cpp index 77e720f5290..6c80899ee1b 100644 --- a/mozilla/content/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLContentSink.cpp @@ -575,6 +575,7 @@ MakeContentObject(nsHTMLTag aNodeType, break; case eHTMLTag_label: rv = NS_NewHTMLLabelElement(aResult, aAtom); + SetForm(*aResult, aForm); break; case eHTMLTag_legend: rv = NS_NewHTMLLegendElement(aResult, aAtom); @@ -1588,14 +1589,14 @@ HTMLContentSink::OpenForm(const nsIParserNode& aNode) AddLeaf(aNode); // add the form to the document - //nsIHTMLDocument* htmlDoc = nsnull; - //if (mDocument && mCurrentForm) { - // rv = mDocument->QueryInterface(kIHTMLDocumentIID, (void**)&htmlDoc); - // if ((NS_OK == rv) && htmlDoc) { - // htmlDoc->AddForm(mCurrentForm); - // NS_RELEASE(htmlDoc); - // } - //} + nsIHTMLDocument* htmlDoc = nsnull; + if (mDocument && mCurrentForm) { + rv = mDocument->QueryInterface(kIHTMLDocumentIID, (void**)&htmlDoc); + if ((NS_OK == rv) && htmlDoc) { + htmlDoc->AddForm(mCurrentForm); + NS_RELEASE(htmlDoc); + } + } return NS_OK; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index c69744e695a..71f509e2ac0 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -2191,7 +2191,6 @@ NS_IMETHODIMP nsHTMLDocument::FindNext(const nsString &aSearchStr, PRBool aMatch // forms related stuff -// XXX remove this if GetForms is sufficient NS_IMETHODIMP nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm) { @@ -2207,14 +2206,12 @@ nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm) // Initialize mForms if necessary... if (nsnull == mForms) { - nsIDOMHTMLCollection* forms = nsnull; - result = GetForms(&forms); - NS_IF_RELEASE(forms); + nsAutoString tag("form"); + mForms = new nsContentList(this, tag); + NS_ADDREF(mForms); } - if (NS_SUCCEEDED(result)) { - mForms->Add(iContent); - } + mForms->Add(iContent); NS_RELEASE(iContent); } return result; diff --git a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp index 18bd4c4b8ab..518aa4eeae2 100644 --- a/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/content/html/style/src/nsHTMLStyleSheet.cpp @@ -1248,6 +1248,10 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext, rv = NS_NewHTMLButtonControlFrame(aContent, aParentFrame, aNewFrame); processChildren = PR_TRUE; } + else if (nsHTMLAtoms::label == aTag) { + rv = NS_NewLabelFrame(aContent, aParentFrame, aNewFrame); + processChildren = PR_TRUE; + } // If we succeeded in creating a frame then set its style context, // process its children (if requested), and initialize the frame diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index c1b1e6e540d..365e426029a 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -123,6 +123,14 @@ GetWindowTemp(nsIView *aView) } +void +nsFileControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + if (mTextFrame) { + mTextFrame->SetFocus(aOn, aRepaint); + } +} + // this is in response to the MouseClick from the containing browse button // XXX still need to get filters from accept attribute void nsFileControlFrame::MouseClicked(nsIPresContext* aPresContext) diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h index 4d2268b2187..3e38ee85048 100644 --- a/mozilla/layout/forms/nsFileControlFrame.h +++ b/mozilla/layout/forms/nsFileControlFrame.h @@ -57,6 +57,7 @@ public: virtual PRBool IsSuccessful(); virtual void Reset(); NS_IMETHOD GetType(PRInt32* aType) const; + void SetFocus(PRBool aOn, PRBool aRepaint); //static PRInt32 gSpacing; diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index 17ba8d64313..1a481aca348 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -339,6 +339,15 @@ nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWid { } +// native widgets don't unset focus explicitly and don't need to repaint +void +nsFormControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + if (mWidget && aOn) { + mWidget->SetFocus(); + } +} + nsresult nsFormControlFrame::GetWidget(nsIWidget** aWidget) { diff --git a/mozilla/layout/forms/nsFormControlFrame.h b/mozilla/layout/forms/nsFormControlFrame.h index c808da66245..09e440a1dc7 100644 --- a/mozilla/layout/forms/nsFormControlFrame.h +++ b/mozilla/layout/forms/nsFormControlFrame.h @@ -169,6 +169,9 @@ public: */ virtual void PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight); + + virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE); + void SetColors(nsIPresContext& aPresContext); virtual void Reset(); diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp index a1e20471de6..32c0ed5a6dc 100644 --- a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp @@ -92,6 +92,8 @@ public: virtual void Reset() {}; virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } + void SetFocus(PRBool aOn, PRBool aRepaint); + void GetDefaultLabel(nsString& aLabel); NS_IMETHOD GetCursorAndContentAt(nsIPresContext& aPresContext, @@ -341,6 +343,16 @@ void ReflowTemp(nsIPresContext& aPresContext, nsHTMLButtonControlFrame* aFrame, aFrame->Invalidate(aRect, PR_TRUE); } +void +nsHTMLButtonControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + mGotFocus = aOn; + if (aRepaint) { + nsRect rect(0, 0, mRect.width, mRect.height); + Invalidate(rect, PR_TRUE); + } +} + // XXX temporary hack code until new style rules are added void nsHTMLButtonControlFrame::AddToPadding(nsIPresContext& aPresContext, @@ -513,6 +525,28 @@ nsHTMLButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, NS_IMETHODIMP nsHTMLButtonControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { + // create our view, we need a view to grab the mouse + nsIView* view; + GetView(view); + if (!view) { + nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, + (void **)&view); + nsIPresShell *presShell = aPresContext.GetShell(); + nsIViewManager *viewMan = presShell->GetViewManager(); + NS_RELEASE(presShell); + + nsIFrame* parWithView; + nsIView *parView; + GetParentWithView(parWithView); + parWithView->GetView(parView); + // the view's size is not know yet, but its size will be kept in synch with our frame. + nsRect boundBox(0, 0, 500, 500); + result = view->Init(viewMan, boundBox, parView, nsnull); + viewMan->InsertChild(parView, view, 0); + SetView(view); + NS_RELEASE(viewMan); + } + // cache our display type const nsStyleDisplay* styleDisplay; GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); @@ -617,27 +651,6 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext& aPresContext, aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; - // create our view, we need a view to grab the mouse - nsIView* view; - GetView(view); - if (!view) { - nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, - (void **)&view); - nsIPresShell *presShell = aPresContext.GetShell(); - nsIViewManager *viewMan = presShell->GetViewManager(); - NS_RELEASE(presShell); - - nsIFrame* parWithView; - nsIView *parView; - GetParentWithView(parWithView); - parWithView->GetView(parView); - nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); - result = view->Init(viewMan, boundBox, parView, nsnull); - viewMan->InsertChild(parView, view, 0); - SetView(view); - NS_RELEASE(viewMan); - } - aStatus = NS_FRAME_COMPLETE; return NS_OK; } diff --git a/mozilla/layout/generic/nsHTMLParts.h b/mozilla/layout/generic/nsHTMLParts.h index 581bbbc6c21..93c772e028b 100644 --- a/mozilla/layout/generic/nsHTMLParts.h +++ b/mozilla/layout/generic/nsHTMLParts.h @@ -332,6 +332,10 @@ extern nsresult NS_NewFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); +extern nsresult +NS_NewLabelFrame(nsIContent* aContent, nsIFrame* aParentFrame, + nsIFrame*& aResult); + extern nsresult NS_NewLegendFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); diff --git a/mozilla/layout/html/base/src/nsHTMLParts.h b/mozilla/layout/html/base/src/nsHTMLParts.h index 581bbbc6c21..93c772e028b 100644 --- a/mozilla/layout/html/base/src/nsHTMLParts.h +++ b/mozilla/layout/html/base/src/nsHTMLParts.h @@ -332,6 +332,10 @@ extern nsresult NS_NewFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); +extern nsresult +NS_NewLabelFrame(nsIContent* aContent, nsIFrame* aParentFrame, + nsIFrame*& aResult); + extern nsresult NS_NewLegendFrame(nsIContent* aContent, nsIFrame* aParentFrame, nsIFrame*& aResult); diff --git a/mozilla/layout/html/content/public/nsIFormControl.h b/mozilla/layout/html/content/public/nsIFormControl.h index d46896ebab8..2c5a1b4b6df 100644 --- a/mozilla/layout/html/content/public/nsIFormControl.h +++ b/mozilla/layout/html/content/public/nsIFormControl.h @@ -37,11 +37,12 @@ class nsIWidget; #define NS_FORM_INPUT_RADIO 12 #define NS_FORM_INPUT_SUBMIT 13 #define NS_FORM_INPUT_TEXT 14 -#define NS_FORM_OPTION 15 -#define NS_FORM_OPTGROUP 16 -#define NS_FORM_LEGEND 17 -#define NS_FORM_SELECT 18 -#define NS_FORM_TEXTAREA 19 +#define NS_FORM_LABEL 15 +#define NS_FORM_OPTION 16 +#define NS_FORM_OPTGROUP 17 +#define NS_FORM_LEGEND 18 +#define NS_FORM_SELECT 19 +#define NS_FORM_TEXTAREA 20 #define NS_FORM_NOTOK 0xFFFFFFF7 #define NS_FORM_NOTSET 0xFFFFFFF7 diff --git a/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp b/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp index b7ba9507699..047abe1a3eb 100644 --- a/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLFieldSetElement.cpp @@ -39,7 +39,7 @@ class nsHTMLFieldSetElement : public nsIDOMHTMLFieldSetElement, public nsIScriptObjectOwner, public nsIDOMEventReceiver, public nsIHTMLContent, - public nsIFormControl + public nsIFormControl { public: nsHTMLFieldSetElement(nsIAtom* aTag); diff --git a/mozilla/layout/html/content/src/nsHTMLFormElement.cpp b/mozilla/layout/html/content/src/nsHTMLFormElement.cpp index 9c8b9a0e0e6..f93da052552 100644 --- a/mozilla/layout/html/content/src/nsHTMLFormElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLFormElement.cpp @@ -161,7 +161,7 @@ nsHTMLFormElement::nsHTMLFormElement(nsIAtom* aTag) mInner.Init(this, aTag); mControls = new nsFormControlList(); NS_ADDREF(mControls); -nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__); +//nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__); } nsHTMLFormElement::~nsHTMLFormElement() @@ -180,10 +180,7 @@ nsHTMLFormElement::~nsHTMLFormElement() NS_RELEASE(mControls); - // XXX make sure this gets moved into nsFormFrame, but not the 1st one!! - //mChildren.Clear(); - //RemoveRadioGroups(); -nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__); +//nsTraceRefcnt::Destroy((nsIForm*)this, __FILE__, __LINE__); } // nsISupports @@ -212,7 +209,7 @@ nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_IMETHODIMP nsHTMLFormElement::AddRef(void) { -nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__); +//nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__); PRInt32 refCnt = mRefCnt; // debugging return ++mRefCnt; } @@ -220,7 +217,7 @@ nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__); NS_IMETHODIMP_(nsrefcnt) nsHTMLFormElement::Release() { -nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__); +//nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__); --mRefCnt; PRUint32 numChildren; GetElementCount(&numChildren); @@ -480,6 +477,7 @@ nsFormControlList::nsFormControlList() nsFormControlList::~nsFormControlList() { + Clear(); } NS_IMETHODIMP diff --git a/mozilla/layout/html/content/src/nsHTMLInputElement.cpp b/mozilla/layout/html/content/src/nsHTMLInputElement.cpp index f0d6b6cb78e..e134db9068f 100644 --- a/mozilla/layout/html/content/src/nsHTMLInputElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLInputElement.cpp @@ -151,7 +151,7 @@ nsHTMLInputElement::nsHTMLInputElement(nsIAtom* aTag) mType = NS_FORM_INPUT_TEXT; // default value mForm = nsnull; mWidget = nsnull; - //nsTraceRefcnt::Create((nsIFormControl*)this, "nsHTMLFormControlElement", __FILE__, __LINE__); + nsTraceRefcnt::Create((nsIFormControl*)this, "nsHTMLFormControlElement", __FILE__, __LINE__); } nsHTMLInputElement::~nsHTMLInputElement() @@ -162,7 +162,7 @@ nsHTMLInputElement::~nsHTMLInputElement() mForm->RemoveElement(this, PR_FALSE); NS_RELEASE(mForm); } - //nsTraceRefcnt::Destroy((nsIFormControl*)this, __FILE__, __LINE__); + nsTraceRefcnt::Destroy((nsIFormControl*)this, __FILE__, __LINE__); } // nsISupports @@ -170,7 +170,7 @@ nsHTMLInputElement::~nsHTMLInputElement() NS_IMETHODIMP_(nsrefcnt) nsHTMLInputElement::AddRef(void) { - //nsTraceRefcnt::AddRef((nsIFormControl*)this, mRefCnt+1, __FILE__, __LINE__); + nsTraceRefcnt::AddRef((nsIFormControl*)this, mRefCnt+1, __FILE__, __LINE__); PRInt32 refCnt = mRefCnt; // debugging return ++mRefCnt; } @@ -196,7 +196,7 @@ nsHTMLInputElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) NS_IMETHODIMP_(nsrefcnt) nsHTMLInputElement::Release() { - //nsTraceRefcnt::Release((nsIFormControl*)this, mRefCnt-1, __FILE__, __LINE__); + nsTraceRefcnt::Release((nsIFormControl*)this, mRefCnt-1, __FILE__, __LINE__); --mRefCnt; if (mRefCnt <= 0) { delete this; diff --git a/mozilla/layout/html/content/src/nsHTMLLabelElement.cpp b/mozilla/layout/html/content/src/nsHTMLLabelElement.cpp index ac8a11f181f..7f4fc31d57f 100644 --- a/mozilla/layout/html/content/src/nsHTMLLabelElement.cpp +++ b/mozilla/layout/html/content/src/nsHTMLLabelElement.cpp @@ -17,6 +17,7 @@ * Netscape Communications Corporation. All Rights Reserved. */ #include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLFormElement.h" #include "nsIScriptObjectOwner.h" #include "nsIDOMEventReceiver.h" #include "nsIHTMLContent.h" @@ -26,13 +27,20 @@ #include "nsIStyleContext.h" #include "nsStyleConsts.h" #include "nsIPresContext.h" +#include "nsIFormControl.h" +#include "nsIForm.h" static NS_DEFINE_IID(kIDOMHTMLLabelElementIID, NS_IDOMHTMLLABELELEMENT_IID); +static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID); +static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID); +static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); class nsHTMLLabelElement : public nsIDOMHTMLLabelElement, public nsIScriptObjectOwner, public nsIDOMEventReceiver, - public nsIHTMLContent + public nsIHTMLContent, + public nsIFormControl + { public: nsHTMLLabelElement(nsIAtom* aTag); @@ -52,6 +60,7 @@ public: // nsIDOMHTMLLabelElement NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm); + NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm); NS_IMETHOD GetAccessKey(nsString& aAccessKey); NS_IMETHOD SetAccessKey(const nsString& aAccessKey); NS_IMETHOD GetHtmlFor(nsString& aHtmlFor); @@ -69,10 +78,17 @@ public: // nsIHTMLContent NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner) + // nsIFormControl + NS_IMETHOD GetType(PRInt32* aType) { return NS_FORM_LABEL; } + NS_IMETHOD SetWidget(nsIWidget* aWidget) { return NS_OK; } + NS_IMETHOD Init() { return NS_OK; } + protected: nsGenericHTMLContainerElement mInner; + nsIForm* mForm; }; +// construction, destruction nsresult NS_NewHTMLLabelElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag) { @@ -91,29 +107,57 @@ nsHTMLLabelElement::nsHTMLLabelElement(nsIAtom* aTag) { NS_INIT_REFCNT(); mInner.Init(this, aTag); + mForm = nsnull; } nsHTMLLabelElement::~nsHTMLLabelElement() { + if (nsnull != mForm) { + // prevent mForm from decrementing its ref count on us + mForm->RemoveElement(this, PR_FALSE); + NS_RELEASE(mForm); + } } +// nsISupports + NS_IMPL_ADDREF(nsHTMLLabelElement) -NS_IMPL_RELEASE(nsHTMLLabelElement) +NS_IMETHODIMP_(nsrefcnt) +nsHTMLLabelElement::Release() +{ + --mRefCnt; + if (mRefCnt <= 0) { + delete this; + return 0; + } else if ((1 == mRefCnt) && mForm) { + mRefCnt = 0; + delete this; + return 0; + } else { + return mRefCnt; + } +} nsresult nsHTMLLabelElement::QueryInterface(REFNSIID aIID, void** aInstancePtr) { NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this) if (aIID.Equals(kIDOMHTMLLabelElementIID)) { - nsIDOMHTMLLabelElement* tmp = this; - *aInstancePtr = (void*) tmp; - mRefCnt++; + *aInstancePtr = (void*)(nsIDOMHTMLLabelElement*)this; + NS_ADDREF_THIS(); + return NS_OK; + } + else if (aIID.Equals(kIFormControlIID)) { + *aInstancePtr = (void*)(nsIFormControl*) this; + NS_ADDREF_THIS(); return NS_OK; } return NS_NOINTERFACE; } +// nsIDOMHTMLLabelElement + nsresult nsHTMLLabelElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) { @@ -128,19 +172,67 @@ nsHTMLLabelElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn) NS_IMETHODIMP nsHTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm) { - *aForm = nsnull;/* XXX */ - return NS_OK; + nsresult result = NS_OK; + *aForm = nsnull; + if (nsnull != mForm) { + nsIDOMHTMLFormElement* formElem = nsnull; + result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem); + if (NS_OK == result) { + *aForm = formElem; + } + } + return result; +} + +// An important assumption is that if aForm is null, the previous mForm will not be released +// This allows nsHTMLFormElement to deal with circular references. +NS_IMETHODIMP +nsHTMLLabelElement::SetForm(nsIDOMHTMLFormElement* aForm) +{ + nsresult result = NS_OK; + if (nsnull == aForm) { + mForm = nsnull; + return NS_OK; + } else { + NS_IF_RELEASE(mForm); + nsIFormControl* formControl = nsnull; + result = QueryInterface(kIFormControlIID, (void**)&formControl); + if ((NS_OK == result) && formControl) { + result = aForm->QueryInterface(kIFormIID, (void**)&mForm); // keep the ref + if ((NS_OK == result) && mForm) { + mForm->AddElement(formControl); + } + NS_RELEASE(formControl); + } + } + return result; } NS_IMPL_STRING_ATTR(nsHTMLLabelElement, AccessKey, accesskey, eSetAttrNotify_None) -NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for, eSetAttrNotify_None) +//NS_IMPL_STRING_ATTR(nsHTMLLabelElement, HtmlFor, _for, eSetAttrNotify_None) + +NS_IMETHODIMP +nsHTMLLabelElement::GetHtmlFor(nsString& aValue) +{ + mInner.GetAttribute(nsHTMLAtoms::_for, aValue); + return NS_OK; +} + +NS_IMETHODIMP +nsHTMLLabelElement::SetHtmlFor(const nsString& aValue) +{ + // trim leading and trailing whitespace + static char whitespace[] = " \r\n\t"; + nsString value(aValue); + value.Trim(whitespace, PR_TRUE, PR_TRUE); + return mInner.SetAttribute(nsHTMLAtoms::defaultvalue, value, PR_TRUE); +} NS_IMETHODIMP nsHTMLLabelElement::StringToAttribute(nsIAtom* aAttribute, const nsString& aValue, nsHTMLValue& aResult) { - // XXX write me return NS_CONTENT_ATTR_NOT_THERE; } @@ -149,7 +241,6 @@ nsHTMLLabelElement::AttributeToString(nsIAtom* aAttribute, nsHTMLValue& aValue, nsString& aResult) const { - // XXX write me return mInner.AttributeToString(aAttribute, aValue, aResult); } @@ -158,7 +249,6 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes, nsIStyleContext* aContext, nsIPresContext* aPresContext) { - // XXX write me nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext); } @@ -179,3 +269,4 @@ nsHTMLLabelElement::HandleDOMEvent(nsIPresContext& aPresContext, return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); } + diff --git a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp index 77e720f5290..6c80899ee1b 100644 --- a/mozilla/layout/html/document/src/nsHTMLContentSink.cpp +++ b/mozilla/layout/html/document/src/nsHTMLContentSink.cpp @@ -575,6 +575,7 @@ MakeContentObject(nsHTMLTag aNodeType, break; case eHTMLTag_label: rv = NS_NewHTMLLabelElement(aResult, aAtom); + SetForm(*aResult, aForm); break; case eHTMLTag_legend: rv = NS_NewHTMLLegendElement(aResult, aAtom); @@ -1588,14 +1589,14 @@ HTMLContentSink::OpenForm(const nsIParserNode& aNode) AddLeaf(aNode); // add the form to the document - //nsIHTMLDocument* htmlDoc = nsnull; - //if (mDocument && mCurrentForm) { - // rv = mDocument->QueryInterface(kIHTMLDocumentIID, (void**)&htmlDoc); - // if ((NS_OK == rv) && htmlDoc) { - // htmlDoc->AddForm(mCurrentForm); - // NS_RELEASE(htmlDoc); - // } - //} + nsIHTMLDocument* htmlDoc = nsnull; + if (mDocument && mCurrentForm) { + rv = mDocument->QueryInterface(kIHTMLDocumentIID, (void**)&htmlDoc); + if ((NS_OK == rv) && htmlDoc) { + htmlDoc->AddForm(mCurrentForm); + NS_RELEASE(htmlDoc); + } + } return NS_OK; } diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index c69744e695a..71f509e2ac0 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -2191,7 +2191,6 @@ NS_IMETHODIMP nsHTMLDocument::FindNext(const nsString &aSearchStr, PRBool aMatch // forms related stuff -// XXX remove this if GetForms is sufficient NS_IMETHODIMP nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm) { @@ -2207,14 +2206,12 @@ nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm) // Initialize mForms if necessary... if (nsnull == mForms) { - nsIDOMHTMLCollection* forms = nsnull; - result = GetForms(&forms); - NS_IF_RELEASE(forms); + nsAutoString tag("form"); + mForms = new nsContentList(this, tag); + NS_ADDREF(mForms); } - if (NS_SUCCEEDED(result)) { - mForms->Add(iContent); - } + mForms->Add(iContent); NS_RELEASE(iContent); } return result; diff --git a/mozilla/layout/html/document/src/ua.css b/mozilla/layout/html/document/src/ua.css index b3d06b33cfe..8b43eff9a17 100644 --- a/mozilla/layout/html/document/src/ua.css +++ b/mozilla/layout/html/document/src/ua.css @@ -417,7 +417,15 @@ IFRAME { INPUT { vertical-align: bottom; } +LABEL { + display: inline; + vertical-align: bottom; + background-color: white; + padding-left: 3px + padding-right: 3px +} BUTTON { + display: inline; vertical-align: bottom; background-color: white; border: 3px outset grey; diff --git a/mozilla/layout/html/forms/src/Makefile b/mozilla/layout/html/forms/src/Makefile index 505bcbc05c6..6dcb1cbc228 100644 --- a/mozilla/layout/html/forms/src/Makefile +++ b/mozilla/layout/html/forms/src/Makefile @@ -36,6 +36,7 @@ CPPSRCS = \ nsFieldSetFrame.cpp \ nsLegendFrame.cpp \ nsHTMLButtonControlFrame.cpp \ + nsLabelFrame.cpp \ $(NULL) MODULE = raptor diff --git a/mozilla/layout/html/forms/src/makefile.win b/mozilla/layout/html/forms/src/makefile.win index bbb87ecb540..9e6a630ccd9 100644 --- a/mozilla/layout/html/forms/src/makefile.win +++ b/mozilla/layout/html/forms/src/makefile.win @@ -25,14 +25,14 @@ REQUIRES=xpcom raptor js CPPSRCS=nsFormFrame.cpp nsFormControlFrame.cpp nsButtonControlFrame.cpp nsCheckboxControlFrame.cpp \ nsFileControlFrame.cpp nsRadioControlFrame.cpp nsTextControlFrame.cpp nsSelectControlFrame.cpp \ - nsFieldSetFrame.cpp nsLegendFrame.cpp nsHTMLButtonControlFrame.cpp + nsFieldSetFrame.cpp nsLegendFrame.cpp nsHTMLButtonControlFrame.cpp nsLabelFrame.cpp CPP_OBJS=.\$(OBJDIR)\nsFormFrame.obj .\$(OBJDIR)\nsFormControlFrame.obj \ .\$(OBJDIR)\nsButtonControlFrame.obj .\$(OBJDIR)\nsCheckboxControlFrame.obj \ .\$(OBJDIR)\nsFileControlFrame.obj .\$(OBJDIR)\nsRadioControlFrame.obj \ .\$(OBJDIR)\nsTextControlFrame.obj .\$(OBJDIR)\nsSelectControlFrame.obj \ .\$(OBJDIR)\nsFieldSetFrame.obj .\$(OBJDIR)\nsLegendFrame.obj \ - .\$(OBJDIR)\nsHTMLButtonControlFrame.obj + .\$(OBJDIR)\nsHTMLButtonControlFrame.obj .\$(OBJDIR)\nsLabelFrame.obj LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \ -I$(PUBLIC)\dom -I$(PUBLIC)\netlib \ diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index c1b1e6e540d..365e426029a 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -123,6 +123,14 @@ GetWindowTemp(nsIView *aView) } +void +nsFileControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + if (mTextFrame) { + mTextFrame->SetFocus(aOn, aRepaint); + } +} + // this is in response to the MouseClick from the containing browse button // XXX still need to get filters from accept attribute void nsFileControlFrame::MouseClicked(nsIPresContext* aPresContext) diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h index 4d2268b2187..3e38ee85048 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h @@ -57,6 +57,7 @@ public: virtual PRBool IsSuccessful(); virtual void Reset(); NS_IMETHOD GetType(PRInt32* aType) const; + void SetFocus(PRBool aOn, PRBool aRepaint); //static PRInt32 gSpacing; diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index 17ba8d64313..1a481aca348 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -339,6 +339,15 @@ nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWid { } +// native widgets don't unset focus explicitly and don't need to repaint +void +nsFormControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + if (mWidget && aOn) { + mWidget->SetFocus(); + } +} + nsresult nsFormControlFrame::GetWidget(nsIWidget** aWidget) { diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.h b/mozilla/layout/html/forms/src/nsFormControlFrame.h index c808da66245..09e440a1dc7 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.h @@ -169,6 +169,9 @@ public: */ virtual void PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight); + + virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE); + void SetColors(nsIPresContext& aPresContext); virtual void Reset(); diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp index a1e20471de6..32c0ed5a6dc 100644 --- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp @@ -92,6 +92,8 @@ public: virtual void Reset() {}; virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } + void SetFocus(PRBool aOn, PRBool aRepaint); + void GetDefaultLabel(nsString& aLabel); NS_IMETHOD GetCursorAndContentAt(nsIPresContext& aPresContext, @@ -341,6 +343,16 @@ void ReflowTemp(nsIPresContext& aPresContext, nsHTMLButtonControlFrame* aFrame, aFrame->Invalidate(aRect, PR_TRUE); } +void +nsHTMLButtonControlFrame::SetFocus(PRBool aOn, PRBool aRepaint) +{ + mGotFocus = aOn; + if (aRepaint) { + nsRect rect(0, 0, mRect.width, mRect.height); + Invalidate(rect, PR_TRUE); + } +} + // XXX temporary hack code until new style rules are added void nsHTMLButtonControlFrame::AddToPadding(nsIPresContext& aPresContext, @@ -513,6 +525,28 @@ nsHTMLButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, NS_IMETHODIMP nsHTMLButtonControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { + // create our view, we need a view to grab the mouse + nsIView* view; + GetView(view); + if (!view) { + nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, + (void **)&view); + nsIPresShell *presShell = aPresContext.GetShell(); + nsIViewManager *viewMan = presShell->GetViewManager(); + NS_RELEASE(presShell); + + nsIFrame* parWithView; + nsIView *parView; + GetParentWithView(parWithView); + parWithView->GetView(parView); + // the view's size is not know yet, but its size will be kept in synch with our frame. + nsRect boundBox(0, 0, 500, 500); + result = view->Init(viewMan, boundBox, parView, nsnull); + viewMan->InsertChild(parView, view, 0); + SetView(view); + NS_RELEASE(viewMan); + } + // cache our display type const nsStyleDisplay* styleDisplay; GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); @@ -617,27 +651,6 @@ nsHTMLButtonControlFrame::Reflow(nsIPresContext& aPresContext, aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; - // create our view, we need a view to grab the mouse - nsIView* view; - GetView(view); - if (!view) { - nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, - (void **)&view); - nsIPresShell *presShell = aPresContext.GetShell(); - nsIViewManager *viewMan = presShell->GetViewManager(); - NS_RELEASE(presShell); - - nsIFrame* parWithView; - nsIView *parView; - GetParentWithView(parWithView); - parWithView->GetView(parView); - nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height); - result = view->Init(viewMan, boundBox, parView, nsnull); - viewMan->InsertChild(parView, view, 0); - SetView(view); - NS_RELEASE(viewMan); - } - aStatus = NS_FRAME_COMPLETE; return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsIFormControlFrame.h b/mozilla/layout/html/forms/src/nsIFormControlFrame.h index 98db501cae9..af08e310ca1 100644 --- a/mozilla/layout/html/forms/src/nsIFormControlFrame.h +++ b/mozilla/layout/html/forms/src/nsIFormControlFrame.h @@ -39,7 +39,11 @@ class nsIFormControlFrame : public nsISupports { public: NS_IMETHOD GetType(PRInt32* aType) const = 0; + NS_IMETHOD GetName(nsString* aName) = 0; + + virtual void SetFocus(PRBool aOn = PR_TRUE, PRBool aRepaint = PR_FALSE) = 0; + virtual void MouseClicked(nsIPresContext* aPresContext) = 0; virtual void Reset() = 0; diff --git a/mozilla/layout/html/forms/src/nsLabelFrame.cpp b/mozilla/layout/html/forms/src/nsLabelFrame.cpp new file mode 100644 index 00000000000..62d5f44e8e3 --- /dev/null +++ b/mozilla/layout/html/forms/src/nsLabelFrame.cpp @@ -0,0 +1,517 @@ +/* -*- 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 "nsHTMLContainerFrame.h" +#include "nsIFormControlFrame.h" +#include "nsHTMLParts.h" +#include "nsIForm.h" +#include "nsIFormControl.h" +#include "nsFormFrame.h" + +#include "nsIRenderingContext.h" +#include "nsIPresContext.h" +#include "nsIPresShell.h" +#include "nsIStyleContext.h" +#include "nsLeafFrame.h" +#include "nsCSSRendering.h" +#include "nsHTMLIIDs.h" +#include "nsISupports.h" +#include "nsHTMLAtoms.h" +#include "nsIImage.h" +#include "nsHTMLImage.h" +#include "nsStyleUtil.h" +#include "nsDOMEvent.h" +#include "nsIDOMHTMLCollection.h" +#include "nsStyleConsts.h" +#include "nsIHTMLAttributes.h" +#include "nsGenericHTMLElement.h" +#include "nsIWidget.h" +#include "nsRepository.h" +#include "nsIView.h" +#include "nsIViewManager.h" +#include "nsViewsCID.h" +#include "nsColor.h" +#include "nsIDocument.h" +#include "nsIHTMLDocument.h" + +//Enumeration of possible mouse states used to detect mouse clicks +enum nsMouseState { + eMouseNone, + eMouseEnter, + eMouseDown, + eMouseExit +}; + +static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID); +static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); +static NS_DEFINE_IID(kViewCID, NS_VIEW_CID); +static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); +static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID); +static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID); + +class nsLabelFrame : public nsHTMLContainerFrame +{ +public: + nsLabelFrame(nsIContent* aContent, nsIFrame* aParentFrame); + + NS_IMETHOD Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect); + + NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + + NS_IMETHOD Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + NS_IMETHOD HandleEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + + NS_IMETHOD GetFor(nsString& aFor); + +protected: + PRBool FindFirstControl(nsIFrame* aParentFrame, nsIFormControlFrame*& aResultFrame); + PRBool FindForControl(nsIFormControlFrame*& aResultFrame); + void GetTranslatedRect(nsRect& aRect); + + virtual ~nsLabelFrame(); + PRIntn GetSkipSides() const; + PRBool mInline; + nsCursor mPreviousCursor; + nsMouseState mLastMouseState; + PRBool mControlIsInside; + nsIFormControlFrame* mControlFrame; + nsRect mTranslatedRect; +}; + +nsresult +NS_NewLabelFrame(nsIContent* aContent, + nsIFrame* aParent, + nsIFrame*& aResult) +{ + aResult = new nsLabelFrame(aContent, aParent); + if (nsnull == aResult) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +nsLabelFrame::nsLabelFrame(nsIContent* aContent, + nsIFrame* aParentFrame) + : nsHTMLContainerFrame(aContent, aParentFrame) +{ + mInline = PR_TRUE; + mLastMouseState = eMouseNone; + mPreviousCursor = eCursor_standard; + mControlIsInside = PR_FALSE; + mControlFrame = nsnull; + mTranslatedRect = nsRect(0,0,0,0); +} + +nsLabelFrame::~nsLabelFrame() +{ +} + + +void +nsLabelFrame::GetTranslatedRect(nsRect& aRect) +{ + nsIView* view; + nsPoint viewOffset(0,0); + GetOffsetFromView(viewOffset, view); + while (nsnull != view) { + nsPoint tempOffset; + view->GetPosition(&tempOffset.x, &tempOffset.y); + viewOffset += tempOffset; + view->GetParent(view); + } + aRect = nsRect(viewOffset.x, viewOffset.y, mRect.width, mRect.height); +} + + +NS_METHOD +nsLabelFrame::HandleEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + if (!mControlFrame) { + return NS_OK; + } + + aEventStatus = nsEventStatus_eIgnore; + nsresult result = NS_OK; + + nsIView* view; + GetView(view); + if (view) { + nsIViewManager* viewMan; + view->GetViewManager(viewMan); + if (viewMan) { + nsIView* grabber; + viewMan->GetMouseEventGrabber(grabber); + if ((grabber == view) || (nsnull == grabber)) { + nsIWidget* window; + PRBool ignore; + + switch (aEvent->message) { + case NS_MOUSE_ENTER: // not implemented yet on frames, 1st mouse move simulates it + mLastMouseState = eMouseEnter; + break; + case NS_MOUSE_LEFT_BUTTON_DOWN: + mControlFrame->SetFocus(PR_TRUE); + mLastMouseState = eMouseDown; + break; + case NS_MOUSE_MOVE: + //printf ("%d mRect=(%d,%d,%d,%d), x=%d, y=%d \n", foo++, mRect.x, mRect.y, mRect.width, mRect.height, aEvent->point.x, aEvent->point.y); + + if (nsnull == grabber) { // simulated mouse enter + GetTranslatedRect(mTranslatedRect); + //printf("%d enter\n", foo++); + viewMan->GrabMouseEvents(view, ignore); + GetWindow(window); + if (window) { + mPreviousCursor = window->GetCursor(); + window->SetCursor(eCursor_select); // set it to something else to work around bug + window->SetCursor(eCursor_standard); + NS_RELEASE(window); + } + mLastMouseState = eMouseEnter; + // simulated mouse exit + } else if (!mTranslatedRect.Contains(aEvent->point)) { + //printf("%d exit\n", foo++); + viewMan->GrabMouseEvents(nsnull, ignore); + GetWindow(window); + if (window) { + window->SetCursor(mPreviousCursor); + NS_RELEASE(window); + } + mLastMouseState = eMouseExit; + } + break; + case NS_MOUSE_LEFT_BUTTON_UP: + if (eMouseDown == mLastMouseState) { + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_MOUSE_EVENT; + event.message = NS_MOUSE_LEFT_CLICK; + mContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status); + + if (nsEventStatus_eConsumeNoDefault != status) { + mControlFrame->MouseClicked(&aPresContext); + } + mLastMouseState = eMouseEnter; + } + break; + case NS_MOUSE_EXIT: // doesn't work for frames, yet + break; + } + aEventStatus = nsEventStatus_eConsumeNoDefault; + NS_RELEASE(viewMan); + return NS_OK; + } + } + } + if (nsnull == mFirstChild) { // XXX see corresponding hack in nsHTMLContainerFrame::DeleteFrame + aEventStatus = nsEventStatus_eConsumeNoDefault; + return NS_OK; + } else { + return nsHTMLContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); + } +} + + +NS_IMETHODIMP +nsLabelFrame::GetFor(nsString& aResult) +{ + nsresult result = NS_FORM_NOTOK; + if (mContent) { + nsIHTMLContent* htmlContent = nsnull; + result = mContent->QueryInterface(kIHTMLContentIID, (void**)&htmlContent); + if ((NS_OK == result) && htmlContent) { + nsHTMLValue value; + result = htmlContent->GetAttribute(nsHTMLAtoms::_for, value); + if (NS_CONTENT_ATTR_HAS_VALUE == result) { + if (eHTMLUnit_String == value.GetUnit()) { + value.GetStringValue(aResult); + } + } + NS_RELEASE(htmlContent); + } + } + return result; +} + +PRBool IsButton(PRInt32 aType) +{ + if ((NS_FORM_INPUT_BUTTON == aType) || (NS_FORM_INPUT_RESET == aType) || + (NS_FORM_INPUT_SUBMIT == aType) || (NS_FORM_BUTTON_BUTTON == aType) || + (NS_FORM_BUTTON_RESET == aType) || (NS_FORM_BUTTON_SUBMIT == aType)) { + return PR_TRUE; + } else { + return PR_FALSE; + } +} + + +PRBool +nsLabelFrame::FindForControl(nsIFormControlFrame*& aResultFrame) +{ + static char whitespace[] = " \r\n\t"; + + nsAutoString forId; + if (NS_CONTENT_ATTR_HAS_VALUE != GetFor(forId)) { + return PR_FALSE; + } + + nsIDocument* iDoc = nsnull; + nsresult result = mContent->GetDocument(iDoc); + if ((NS_OK != result) || (nsnull == iDoc)) { + return PR_FALSE; + } + + nsIHTMLDocument* htmlDoc = nsnull; + result = iDoc->QueryInterface(kIHTMLDocumentIID, (void**)&htmlDoc); + if ((NS_OK != result) || (nsnull == htmlDoc)) { + NS_RELEASE(iDoc); + return PR_FALSE; + } + + nsIPresShell *shell = iDoc->GetShellAt(0); + if (nsnull == shell) { + NS_RELEASE(iDoc); + NS_RELEASE(htmlDoc); + return PR_FALSE; + } + + nsIDOMHTMLCollection* forms = nsnull; + htmlDoc->GetForms(&forms); + PRUint32 numForms; + forms->GetLength(&numForms); + + PRBool returnValue = PR_FALSE; + + for (PRUint32 formX = 0; formX < numForms; formX++) { + nsIContent* iContent = nsnull; + nsIDOMNode* node = nsnull; + forms->Item(formX, &node); + if (nsnull == node) { + continue; + } + nsIForm* form = nsnull; + result = node->QueryInterface(kIFormIID, (void**)&form); + if ((NS_OK != result) || (nsnull == form)) { + continue; + } + PRUint32 numControls; + form->GetElementCount(&numControls); + for (PRUint32 controlX = 0; controlX < numControls; controlX++) { + nsIFormControl* control = nsnull; + form->GetElementAt(controlX, &control); + if (nsnull == control) { + continue; + } + // buttons have implicit labels and we don't allow them to have explicit ones + PRInt32 type; + control->GetType(&type); + if (!IsButton(type)) { + nsIHTMLContent* htmlContent = nsnull; + result = control->QueryInterface(kIHTMLContentIID, (void**)&htmlContent); + if ((NS_OK == result) && (nsnull != htmlContent)) { + nsHTMLValue value; + nsAutoString id; + result = htmlContent->GetAttribute(nsHTMLAtoms::id, value); + if ((NS_CONTENT_ATTR_HAS_VALUE == result) && (eHTMLUnit_String == value.GetUnit())) { + value.GetStringValue(id); + id.Trim(whitespace, PR_TRUE, PR_TRUE); + if (id.Equals(forId)) { + nsIFrame* frame = shell->FindFrameWithContent(htmlContent); + if (nsnull != frame) { + nsIFormControlFrame* fcFrame = nsnull; + result = frame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame); + if ((NS_OK == result) && (nsnull != fcFrame)) { + aResultFrame = fcFrame; + NS_RELEASE(fcFrame); + returnValue = PR_TRUE; + } + } + } + } + NS_RELEASE(htmlContent); + } + } + NS_RELEASE(control); + } + } + NS_RELEASE(iDoc); + NS_RELEASE(htmlDoc); + NS_RELEASE(forms); + NS_RELEASE(shell); + + return returnValue; +} + +PRBool +nsLabelFrame::FindFirstControl(nsIFrame* aParentFrame, nsIFormControlFrame*& aResultFrame) +{ + nsIFrame* child = nsnull; + aParentFrame->FirstChild(child); + while (nsnull != child) { + nsIFormControlFrame* fcFrame = nsnull; + nsresult result = child->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame); + if ((NS_OK == result) && fcFrame) { + PRInt32 type; + fcFrame->GetType(&type); + // buttons have implicit labels and we don't allow them to have explicit ones + if (!IsButton(type)) { + aResultFrame = fcFrame; + return PR_TRUE; + } + NS_RELEASE(fcFrame); + } else if (FindFirstControl(child, aResultFrame)) { + return PR_TRUE; + } + child->GetNextSibling(child); + } + return PR_FALSE; +} + + +NS_IMETHODIMP +nsLabelFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) +{ + // create our view, we need a view to grab the mouse + nsIView* view; + GetView(view); + if (!view) { + nsresult result = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, + (void **)&view); + nsIPresShell *presShell = aPresContext.GetShell(); + nsIViewManager *viewMan = presShell->GetViewManager(); + NS_RELEASE(presShell); + + nsIFrame* parWithView; + nsIView *parView; + GetParentWithView(parWithView); + parWithView->GetView(parView); + // the view's size is not know yet, but its size will be kept in synch with our frame. + nsRect boundBox(0, 0, 500, 500); + result = view->Init(viewMan, boundBox, parView, nsnull); + viewMan->InsertChild(parView, view, 0); + SetView(view); + NS_RELEASE(viewMan); + } + + // cache our display type + const nsStyleDisplay* styleDisplay; + GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); + mInline = (NS_STYLE_DISPLAY_BLOCK != styleDisplay->mDisplay); + + PRUint8 flags = (mInline) ? NS_BODY_SHRINK_WRAP : 0; + NS_NewBodyFrame(mContent, this, mFirstChild, flags); + + // Resolve style and set the style context + nsIStyleContext* styleContext = + aPresContext.ResolveStyleContextFor(mContent, this); + mFirstChild->SetStyleContext(&aPresContext, styleContext); + NS_RELEASE(styleContext); + + // Set the geometric and content parent for each of the child frames + for (nsIFrame* frame = aChildList; nsnull != frame; frame->GetNextSibling(frame)) { + frame->SetGeometricParent(mFirstChild); + frame->SetContentParent(mFirstChild); + } + + // Queue up the frames for the body frame + return mFirstChild->Init(aPresContext, aChildList); +} + +NS_IMETHODIMP +nsLabelFrame::Paint(nsIPresContext& aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect) +{ + return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); +} + +NS_IMETHODIMP +nsLabelFrame::Reflow(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (nsnull == mControlFrame) { + // check to see if a form control is referenced via the "for" attribute + if (FindForControl(mControlFrame)) { + mControlIsInside = PR_FALSE; + } else { + // find the 1st (and should be only) form control contained within if there is no "for" + mControlIsInside = FindFirstControl(this, mControlFrame); + } + } + + nsSize availSize(aReflowState.maxSize); + + // reflow the child + nsHTMLReflowState reflowState(aPresContext, mFirstChild, aReflowState, availSize); + ReflowChild(mFirstChild, aPresContext, aDesiredSize, reflowState, aStatus); + + // get border and padding + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + nsMargin borderPadding; + spacing->CalcBorderPaddingFor(this, borderPadding); + + // Place the child + nsRect rect = nsRect(borderPadding.left, borderPadding.top, aDesiredSize.width, aDesiredSize.height); + mFirstChild->SetRect(rect); + + // add in our border and padding to the size of the child + aDesiredSize.width += borderPadding.left + borderPadding.right; + aDesiredSize.height += borderPadding.top + borderPadding.bottom; + + // adjust our max element size, if necessary + if (aDesiredSize.maxElementSize) { + aDesiredSize.maxElementSize->width += borderPadding.left + borderPadding.right; + aDesiredSize.maxElementSize->height += borderPadding.top + borderPadding.bottom; + } + + // if we are constrained and the child is smaller, use the constrained values + if (aReflowState.HaveConstrainedWidth() && (aDesiredSize.width < aReflowState.minWidth)) { + aDesiredSize.width = aReflowState.minWidth; + } + if (aReflowState.HaveConstrainedHeight() && (aDesiredSize.height < aReflowState.minHeight)) { + aDesiredSize.height = aReflowState.minHeight; + } + + aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.descent = 0; + + aStatus = NS_FRAME_COMPLETE; + return NS_OK; +} + + +PRIntn +nsLabelFrame::GetSkipSides() const +{ + return 0; +} + + diff --git a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp index 18bd4c4b8ab..518aa4eeae2 100644 --- a/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/html/style/src/nsHTMLStyleSheet.cpp @@ -1248,6 +1248,10 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext, rv = NS_NewHTMLButtonControlFrame(aContent, aParentFrame, aNewFrame); processChildren = PR_TRUE; } + else if (nsHTMLAtoms::label == aTag) { + rv = NS_NewLabelFrame(aContent, aParentFrame, aNewFrame); + processChildren = PR_TRUE; + } // If we succeeded in creating a frame then set its style context, // process its children (if requested), and initialize the frame diff --git a/mozilla/layout/style/nsHTMLStyleSheet.cpp b/mozilla/layout/style/nsHTMLStyleSheet.cpp index 18bd4c4b8ab..518aa4eeae2 100644 --- a/mozilla/layout/style/nsHTMLStyleSheet.cpp +++ b/mozilla/layout/style/nsHTMLStyleSheet.cpp @@ -1248,6 +1248,10 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext, rv = NS_NewHTMLButtonControlFrame(aContent, aParentFrame, aNewFrame); processChildren = PR_TRUE; } + else if (nsHTMLAtoms::label == aTag) { + rv = NS_NewLabelFrame(aContent, aParentFrame, aNewFrame); + processChildren = PR_TRUE; + } // If we succeeded in creating a frame then set its style context, // process its children (if requested), and initialize the frame diff --git a/mozilla/layout/style/ua.css b/mozilla/layout/style/ua.css index b3d06b33cfe..8b43eff9a17 100644 --- a/mozilla/layout/style/ua.css +++ b/mozilla/layout/style/ua.css @@ -417,7 +417,15 @@ IFRAME { INPUT { vertical-align: bottom; } +LABEL { + display: inline; + vertical-align: bottom; + background-color: white; + padding-left: 3px + padding-right: 3px +} BUTTON { + display: inline; vertical-align: bottom; background-color: white; border: 3px outset grey; diff --git a/mozilla/webshell/tests/viewer/samples/test8.html b/mozilla/webshell/tests/viewer/samples/test8.html index 1e1ba116ec5..f207499af95 100644 --- a/mozilla/webshell/tests/viewer/samples/test8.html +++ b/mozilla/webshell/tests/viewer/samples/test8.html @@ -27,20 +27,22 @@ BUTTON {
-
+
html 4 fieldset/legend
+ +
 Find it Fast 
-  

- +
html 4 button

@@ -49,18 +51,26 @@ and a background image. It will also submit the form.

+
html 4 labels
+ + + + + + +
+
+ +
+ +

+
   -

-checkboxes:        a password:  

- radio1 -
- radio2 -