implemented <LABEL>; document maintains list of forms as created; form element properly releases form controls.

This commit is contained in:
karnaze%netscape.com 1998-10-22 23:00:37 +00:00
parent 4f6efe39c9
commit 2a0c2366bb
36 changed files with 953 additions and 141 deletions

View File

@ -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

View File

@ -39,7 +39,7 @@ class nsHTMLFieldSetElement : public nsIDOMHTMLFieldSetElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl
{
public:
nsHTMLFieldSetElement(nsIAtom* aTag);

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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)
{

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -39,7 +39,7 @@ class nsHTMLFieldSetElement : public nsIDOMHTMLFieldSetElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
public nsIFormControl
{
public:
nsHTMLFieldSetElement(nsIAtom* aTag);

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -36,6 +36,7 @@ CPPSRCS = \
nsFieldSetFrame.cpp \
nsLegendFrame.cpp \
nsHTMLButtonControlFrame.cpp \
nsLabelFrame.cpp \
$(NULL)
MODULE = raptor

View File

@ -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 \

View File

@ -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)

View File

@ -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;

View File

@ -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)
{

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -27,20 +27,22 @@ BUTTON {
<BR>
<FORM METHOD="GET" ACTION="http://search.yahoo.com/bin/search" NAME="searchform">
<FIELDSET style="background-color: rgb(200, 220, 240); display: inline; border: 2px solid black; padding: 10px;">
<div align=center><bold><font size=2>html 4 fieldset/legend</font></bold></div>
<INPUT type=image src=raptor.jpg width=50 height=50 name=imageSubmit>
<FIELDSET style="background-color: rgb(200, 220, 240); display: inline; border: 2px solid black; margin-left: 10px; padding: 10px;">
<LEGEND style="background-color:rgb(180, 200, 220); border: 1px solid gray; padding: 0px;" align=left>&nbsp;Find it <b>Fast</b>&nbsp;</LEGEND>
<INPUT type=text value=travel NAME="p" SIZE=15 MAXLENGTH=80 style="margin-right:10px; background-color: rgb(190, 190, 190);">
<INPUT type=submit value="GO">
<INPUT TYPE="HIDDEN" NAME="a" VALUE="n">
</FIELDSET>
&nbsp;&nbsp<INPUT type=image src=raptor.jpg width=50 height=50 name=imageSubmit>
<BR><BR>
<div align=center><bold><font size=2>html 4 button</font></bold></div>
<BUTTON type=submit style="border: 5px outset gray; padding: 3px;">
<font size=4><B>This big button contains a table
<font size=4><B>This button contains a table
<table border=3><TR border=1><TD>CELL 1</TD><TD>CELL 2<TD></TR>
<TR><TD>CELL 3</TD><TD>CELL 4</TD></TR></table>
and a background image. It will also submit the form.
and a background image.
<BR>It will also submit the form.
</B></font>
</BUTTON>
<BR>
@ -49,18 +51,26 @@ and a background image. It will also submit the form.
<BR><BR>
<FORM METHOD="POST" ACTION="http://www.mcp.com/cgi-bin/post-query" NAME="echo">
<div align=center><bold><font size=2>html 4 labels</font></bold></div>
<table>
<tr>
<td><label for=radio1 style="margin-right: 5px;">radio 1 label</label></td>
<td><input id=radio1 type=radio name=radio></td></tr>
<tr>
<td><label for=radio2 style="border: 1px solid blue; margin-right: 5px;">radio 2</label></td>
<td><input id=radio2 type=radio name=radio></td></tr></table>
<BR>
<label><input type=checkbox name=check1 checked>checkbox 1</label>
<BR>
<label><input type=checkbox name=check2>checkbox 2</label>
<BR><BR>
<HR>
<textarea name=a rows=4 cols=10 value="a textarea">a textarea</textarea>
&nbsp;&nbsp;
<textarea name=a id=textarea1 value="a textarea">another textarea
size, font set by css</textarea>
<BR><BR>
checkboxes:&nbsp;&nbsp; <input type=checkbox name=check1 checked> &nbsp;<input type=checkbox name=check2>
&nbsp;&nbsp; a password:&nbsp;&nbsp;<INPUT TYPE="PASSWORD">
<BR><BR>
<input type=radio name=group1> radio1
<BR>
<input type=radio name=group1 checked> radio2
<BR><BR>
<select name=select2 id=select1 size=4 multiple>
<option>option 1</option>
<option>option 2</option>