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 {