Converted forms to use the new content model classes and better separate content from layout.

This commit is contained in:
karnaze%netscape.com 1998-09-23 17:16:51 +00:00
Родитель e106e55c80
Коммит fb883f1869
77 изменённых файлов: 8316 добавлений и 6327 удалений

Просмотреть файл

@ -17,6 +17,6 @@
DEPTH=..\..\..
DIRS=src
DIRS=src public
include <$(DEPTH)\layout\config\rules.mak>

Просмотреть файл

@ -0,0 +1,25 @@
#!nmake
#
# 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.
DEPTH=..\..\..\..
EXPORTS=nsIFormControl.h nsIForm.h
MODULE=raptor
include <$(DEPTH)\layout\config\rules.mak>

Просмотреть файл

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIForm_h___
#define nsIForm_h___
#include "nsISupports.h"
class nsIFormControl;
#define NS_FORM_METHOD_GET 0
#define NS_FORM_METHOD_POST 1
#define NS_FORM_ENCTYPE_URLENCODED 0
#define NS_FORM_ENCTYPE_MULTIPART 1
// IID for the nsIFormManager interface
#define NS_IFORM_IID \
{ 0xb7e94510, 0x4c19, 0x11d2, \
{ 0x80, 0x3f, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
/**
* This interface provides a complete set of methods dealing with elements which
* belong to a form element. When nsIDOMHTMLCollection allows write operations
**/
class nsIForm : public nsISupports {
public:
/**
* Add an element to end of this form's list of elements
* @param aElement the element to add
* @return NS_OK if the element was successfully added
*/
NS_IMETHOD AddElement(nsIFormControl* aElement) = 0;
/**
* Get the element at a specified index position
* @param aIndex the index
* @param aElement the element at that index
* @return NS_OK if there was an element at that position, -1 otherwise
*/
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const = 0;
/**
* Get the number of elements in this form
* @param aCount the number of elements
* @return NS_OK if there was an element at that position, -1 otherwise
*/
NS_IMETHOD GetElementCount(PRUint32* aCount) const = 0;
/**
* Remove an element from this form's list of elements
* @param aElement the element to remove
* @param aChildIsRef if PR_TRUE, the elements ref count will be decremented
* otherwise not. This is to facilitate circular references.
* @return NS_OK if the element was successfully removed.
*/
NS_IMETHOD RemoveElement(nsIFormControl* aElement,
PRBool aChildIsRef = PR_TRUE) = 0;
};
#endif /* nsIForm_h___ */

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIFormControl_h___
#define nsIFormControl_h___
#include "nsISupports.h"
class nsIDOMHTMLFormElement;
class nsIWidget;
#define NS_FORM_BROWSE 0
#define NS_FORM_BUTTON 1
#define NS_FORM_FIELDSET 2
#define NS_FORM_INPUT_BUTTON 3
#define NS_FORM_INPUT_CHECKBOX 4
#define NS_FORM_INPUT_FILE 5
#define NS_FORM_INPUT_HIDDEN 6
#define NS_FORM_INPUT_RESET 7
#define NS_FORM_INPUT_IMAGE 8
#define NS_FORM_INPUT_PASSWORD 9
#define NS_FORM_INPUT_RADIO 10
#define NS_FORM_INPUT_SUBMIT 11
#define NS_FORM_INPUT_TEXT 12
#define NS_FORM_OPTION 13
#define NS_FORM_OPTGROUP 14
#define NS_FORM_LEGEND 15
#define NS_FORM_SELECT 16
#define NS_FORM_TEXTAREA 17
#define NS_FORM_NOTOK 0xFFFFFFF7
#define NS_FORM_NOTSET 0xFFFFFFF7
#define NS_IFORMCONTROL_IID \
{ 0x282ff440, 0xcd7e, 0x11d1, \
{0x89, 0xad, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/**
* Interface which all form controls (e.g. buttons, checkboxes, text,
* radio buttons, select, etc) implement in addition to their dom specific interface.
**/
class nsIFormControl : public nsISupports {
public:
/**
* Get the form for this form control.
* @param aForm the form to get
* @return NS_OK
*/
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm) = 0;
/**
* Set the form for this form control.
* @param aForm the form
* @return NS_OK
*/
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm) = 0;
/**
* Get the type of this control
* @param aType the type to be returned
* @return NS_OK
*/
NS_IMETHOD GetType(PRInt32* aType) = 0;
NS_IMETHOD SetWidget(nsIWidget* aWidget) = 0;
NS_IMETHOD Init() = 0;
};
#endif /* nsIFormControl_h___ */

Просмотреть файл

@ -936,8 +936,8 @@ nsGenericHTMLElement::SetClassName(const nsString& aClassName)
nsresult
nsGenericHTMLElement::GetDocument(nsIDocument*& aResult) const
{
aResult = mDocument;
NS_IF_ADDREF(mDocument);
aResult = mDocument;
return NS_OK;
}
@ -2253,6 +2253,15 @@ static nsGenericHTMLElement::EnumTable kDivAlignTable[] = {
{ 0 }
};
static nsGenericHTMLElement::EnumTable kFormAlignTable[] = {
{ "left", NS_STYLE_TEXT_ALIGN_LEFT },
{ "right", NS_STYLE_TEXT_ALIGN_RIGHT },
{ "bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM },
{ "top", NS_STYLE_VERTICAL_ALIGN_TOP },
{ "middle", NS_STYLE_VERTICAL_ALIGN_MIDDLE },
{ 0 }
};
static nsGenericHTMLElement::EnumTable kFrameborderQuirksTable[] = {
{ "yes", NS_STYLE_FRAME_YES },
{ "no", NS_STYLE_FRAME_NO },
@ -2331,6 +2340,20 @@ nsGenericHTMLElement::AlignValueToString(const nsHTMLValue& aValue,
return EnumValueToString(aValue, kAlignTable, aResult);
}
PRBool
nsGenericHTMLElement::ParseFormAlignValue(const nsString& aString,
nsHTMLValue& aResult)
{
return ParseEnumValue(aString, kFormAlignTable, aResult);
}
PRBool
nsGenericHTMLElement::FormAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult)
{
return EnumValueToString(aValue, kFormAlignTable, aResult);
}
PRBool
nsGenericHTMLElement::TableHAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult)

Просмотреть файл

@ -230,6 +230,9 @@ public:
static PRBool ParseAlignValue(const nsString& aString, nsHTMLValue& aResult);
static PRBool ParseFormAlignValue(const nsString& aString,
nsHTMLValue& aResult);
static PRBool ParseDivAlignValue(const nsString& aString,
nsHTMLValue& aResult);
@ -248,6 +251,8 @@ public:
static PRBool AlignValueToString(const nsHTMLValue& aValue,
nsString& aResult);
static PRBool FormAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult);
static PRBool DivAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult);

Просмотреть файл

@ -154,6 +154,7 @@ NS_IMPL_STRING_ATTR(nsHTMLButtonElement, AccessKey, accesskey, eSetAttrNotify_No
NS_IMPL_BOOL_ATTR(nsHTMLButtonElement, Disabled, disabled, eSetAttrNotify_Render)
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Name, name, eSetAttrNotify_Restart)
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Type, type, eSetAttrNotify_Restart)
NS_IMPL_INT_ATTR(nsHTMLButtonElement, TabIndex, tabindex, eSetAttrNotify_None)
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Value, value, eSetAttrNotify_Render)
NS_IMETHODIMP

Просмотреть файл

@ -16,7 +16,12 @@
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIForm.h"
#include "nsIFormControl.h"
#include "nsIFormManager.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMNSHTMLFormElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +31,25 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIFrame.h"
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kIFormManagerIID, NS_IFORMMANAGER_IID);
static NS_DEFINE_IID(kIDOMNSHTMLFormElementIID, NS_IDOMNSHTMLFORMELEMENT_IID);
class nsFormControlList;
// nsHTMLFormElement
class nsHTMLFormElement : public nsIDOMHTMLFormElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIForm
{
public:
nsHTMLFormElement(nsIAtom* aTag);
@ -78,10 +95,45 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIForm
NS_IMETHOD AddElement(nsIFormControl* aElement);
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
NS_IMETHOD RemoveElement(nsIFormControl* aElement, PRBool aChildIsRef = PR_TRUE);
protected:
nsFormControlList* mControls;
nsGenericHTMLLeafElement mInner;
};
// nsFormControlList
class nsFormControlList : public nsIDOMHTMLCollection, public nsIScriptObjectOwner {
public:
nsFormControlList();
virtual ~nsFormControlList();
void Clear();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
NS_IMETHOD ResetScriptObject();
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
// Called to tell us that the form is going away and that we
// should drop our (non ref-counted) reference to it
void ReleaseForm();
void *mScriptObject;
nsVoidArray mElements;
};
// nsHTMLFormElement implementation
// construction, destruction
nsresult
NS_NewHTMLFormElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -100,29 +152,80 @@ nsHTMLFormElement::nsHTMLFormElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mControls = new nsFormControlList();
NS_ADDREF(mControls);
nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__);
}
nsHTMLFormElement::~nsHTMLFormElement()
{
// set the controls to have no form
PRUint32 numControls;
GetElementCount(&numControls);
for (PRUint32 i = 0; i < numControls; i++) {
// avoid addref to child
nsIFormControl* control = (nsIFormControl*)mControls->mElements.ElementAt(i);
if (control) {
// it is assummed that passing in nsnull will not release formControl's previous form
control->SetForm(nsnull);
}
}
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__);
}
NS_IMPL_ADDREF(nsHTMLFormElement)
NS_IMPL_RELEASE(nsHTMLFormElement)
nsresult
// nsISupports
NS_IMETHODIMP
nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLFormElementIID)) {
nsIDOMHTMLFormElement* tmp = this;
*aInstancePtr = (void*) tmp;
mRefCnt++;
if (aIID.Equals(kIFormIID)) {
*aInstancePtr = (void*)(nsIForm*)this;
AddRef();
return NS_OK;
}
else if (aIID.Equals(kIDOMHTMLFormElementIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLFormElement*)this;
AddRef();
return NS_OK;
}
else if (aIID.Equals(kIDOMNSHTMLFormElementIID)) {
*aInstancePtr = (void*)(nsIDOMNSHTMLFormElement*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsHTMLFormElement::AddRef(void)
{
nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__);
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLFormElement::Release()
{
nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__);
--mRefCnt;
PRUint32 numChildren;
GetElementCount(&numChildren);
if ((int)mRefCnt == numChildren) {
mRefCnt = 0;
delete this;
return 0;
}
return mRefCnt;
}
// nsIDOMHTMLFormElement
nsresult
nsHTMLFormElement::CloneNode(nsIDOMNode** aReturn)
{
@ -135,9 +238,10 @@ nsHTMLFormElement::CloneNode(nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsHTMLFormElement::GetElements(nsIDOMHTMLCollection** aResult)
nsHTMLFormElement::GetElements(nsIDOMHTMLCollection** aElements)
{
// XXX write me
*aElements = mControls;
NS_ADDREF(mControls);
return NS_OK;
}
@ -154,26 +258,85 @@ NS_IMPL_STRING_ATTR(nsHTMLFormElement, Method, method, eSetAttrNotify_None)
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Target, target, eSetAttrNotify_None)
NS_IMETHODIMP
nsHTMLFormElement::Reset()
nsHTMLFormElement::Submit()
{
// XXX
return NS_OK;
// XXX Need to do something special with mailto: or news: URLs
nsIDocument* doc = nsnull;
nsresult result = GetDocument(doc);
if ((NS_OK == result) && doc) {
nsIPresShell *shell = doc->GetShellAt(0);
if (nsnull != shell) {
nsIFrame* frame = shell->FindFrameWithContent(this);
if (frame) {
nsIFormManager* formMan = nsnull;
nsresult result = frame->QueryInterface(kIFormManagerIID, (void**)&formMan);
if ((NS_OK == result) && formMan) {
nsIPresContext *context = shell->GetPresContext();
if (nsnull != context) {
// XXX We're currently passing in null for the frame.
// It works for now, but might not always
// be correct. In the future, we might not need the
// frame to be passed to the link handler.
result = formMan->OnSubmit(context, nsnull);
NS_RELEASE(context);
}
}
}
NS_RELEASE(shell);
}
NS_RELEASE(doc);
}
return result;
}
NS_IMETHODIMP
nsHTMLFormElement::Submit()
nsHTMLFormElement::Reset()
{
// XXX
return NS_OK;
}
// XXX Need to do something special with mailto: or news: URLs
nsIDocument* doc = nsnull;
nsresult result = GetDocument(doc);
if ((NS_OK == result) && doc) {
nsIPresShell *shell = doc->GetShellAt(0);
if (nsnull != shell) {
nsIFrame* frame = shell->FindFrameWithContent(this);
if (frame) {
nsIFormManager* formMan = nsnull;
nsresult result = frame->QueryInterface(kIFormManagerIID, (void**)&formMan);
if ((NS_OK == result) && formMan) {
result = formMan->OnReset();
}
}
NS_RELEASE(shell);
}
}
return result;
}
static nsGenericHTMLElement::EnumTable kFormMethodTable[] = {
{ "get", NS_FORM_METHOD_GET },
{ "post", NS_FORM_METHOD_POST },
{ 0 }
};
static nsGenericHTMLElement::EnumTable kFormEnctypeTable[] = {
{ "multipart/form-data", NS_FORM_ENCTYPE_MULTIPART },
{ "application/x-www-form-urlencoded", NS_FORM_ENCTYPE_URLENCODED },
{ 0 }
};
NS_IMETHODIMP
nsHTMLFormElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::method) {
nsGenericHTMLElement::ParseEnumValue(aValue, kFormMethodTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::enctype) {
nsGenericHTMLElement::ParseEnumValue(aValue, kFormEnctypeTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -182,7 +345,18 @@ nsHTMLFormElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
if (aAttribute == nsHTMLAtoms::method) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::EnumValueToString(aValue, kFormMethodTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::enctype) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::EnumValueToString(aValue, kFormEnctypeTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -214,3 +388,166 @@ nsHTMLFormElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIForm
NS_IMETHODIMP
nsHTMLFormElement::GetElementCount(PRUint32* aCount) const
{
mControls->GetLength(aCount);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFormElement::GetElementAt(PRInt32 aIndex, nsIFormControl** aFormControl) const
{
*aFormControl = (nsIFormControl*) mControls->mElements.ElementAt(aIndex);
NS_IF_ADDREF(*aFormControl);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
{
PRBool rv = mControls->mElements.AppendElement(aChild);
if (rv) {
NS_ADDREF(aChild);
}
return rv;
}
NS_IMETHODIMP
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild, PRBool aChildIsRef)
{
PRBool rv = mControls->mElements.RemoveElement(aChild);
if (rv && aChildIsRef) {
NS_RELEASE(aChild);
}
return rv;
}
// nsFormControlList implementation, this could go away if there were a lightweight collection implementation somewhere
nsFormControlList::nsFormControlList()
{
mRefCnt = 0;
mScriptObject = nsnull;
}
nsFormControlList::~nsFormControlList()
{
}
NS_IMETHODIMP
nsFormControlList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
void
nsFormControlList::Clear()
{
PRUint32 numElements = mElements.Count();
for (PRUint32 i = 0; i < numElements; i++) {
nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
NS_IF_RELEASE(elem);
}
}
nsresult nsFormControlList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsFormControlList)
NS_IMPL_RELEASE(nsFormControlList)
nsresult nsFormControlList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLCollection(aContext, (nsISupports *)(nsIDOMHTMLCollection *)this, nsnull, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
nsresult nsFormControlList::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
// nsIDOMHTMLCollection interface
NS_IMETHODIMP
nsFormControlList::GetLength(PRUint32* aLength)
{
*aLength = mElements.Count();
return NS_OK;
}
NS_IMETHODIMP
nsFormControlList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(aIndex);
if (control) {
return control->QueryInterface(kIDOMNodeIID, (void**)aReturn); // keep the ref
}
*aReturn = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsFormControlList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
PRUint32 count = mElements.Count();
nsresult result = NS_OK;
*aReturn = nsnull;
for (PRUint32 i = 0; i < count && *aReturn == nsnull; i++) {
nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(i);
if (nsnull != control) {
nsIContent *content;
result = control->QueryInterface(kIContentIID, (void **)&content);
if (NS_OK == result) {
nsAutoString name;
// XXX Should it be an EqualsIgnoreCase?
if (((content->GetAttribute("NAME", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name))) ||
((content->GetAttribute("ID", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name)))) {
result = control->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
NS_RELEASE(content);
}
}
}
return result;
}

Просмотреть файл

@ -17,6 +17,7 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -27,15 +28,24 @@
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIHTMLAttributes.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIWidget.h"
#include "nsITextWidget.h"
// XXX align=left, hspace, vspace, border? other nav4 attrs
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_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);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
class nsHTMLInputElement : public nsIDOMHTMLInputElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
{
public:
nsHTMLInputElement(nsIAtom* aTag);
@ -105,10 +115,21 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFormControl
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm);
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
protected:
nsGenericHTMLLeafElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
nsIForm* mForm;
PRInt32 mType;
};
// construction, destruction
nsresult
NS_NewHTMLInputElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -127,29 +148,70 @@ nsHTMLInputElement::nsHTMLInputElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mType = NS_FORM_INPUT_TEXT; // default value
mForm = nsnull;
mWidget = nsnull;
nsTraceRefcnt::Create((nsIFormControl*)this, "nsHTMLFormControlElement", __FILE__, __LINE__);
}
nsHTMLInputElement::~nsHTMLInputElement()
{
NS_IF_RELEASE(mWidget);
if (nsnull != mForm) {
// prevent mForm from decrementing its ref count on us
mForm->RemoveElement(this, PR_FALSE);
NS_RELEASE(mForm);
}
nsTraceRefcnt::Destroy((nsIFormControl*)this, __FILE__, __LINE__);
}
NS_IMPL_ADDREF(nsHTMLInputElement)
// nsISupports
NS_IMPL_RELEASE(nsHTMLInputElement)
NS_IMETHODIMP_(nsrefcnt)
nsHTMLInputElement::AddRef(void)
{
nsTraceRefcnt::AddRef((nsIFormControl*)this, mRefCnt+1, __FILE__, __LINE__);
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
NS_IMETHODIMP
nsHTMLInputElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLInputElementIID)) {
nsIDOMHTMLInputElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLInputElement*) 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;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLInputElement::Release()
{
nsTraceRefcnt::Release((nsIFormControl*)this, mRefCnt-1, __FILE__, __LINE__);
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else if ((1 == mRefCnt) && mForm) {
mRefCnt = 0;
delete this;
return 0;
} else {
return mRefCnt;
}
}
// nsIDOMHTMLInputElement
nsresult
nsHTMLInputElement::CloneNode(nsIDOMNode** aReturn)
{
@ -164,7 +226,14 @@ nsHTMLInputElement::CloneNode(nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLInputElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;/* XXX */
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
@ -195,66 +264,45 @@ nsHTMLInputElement::GetType(nsString& aValue)
NS_IMETHODIMP
nsHTMLInputElement::Blur()
{
// XXX write me
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Focus()
{
// XXX write me
if (nsnull != mWidget) {
mWidget->SetFocus();
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Select()
{
// XXX write me
if ((NS_FORM_INPUT_TEXT == mType) && (nsnull != mWidget)) {
nsITextWidget *textWidget;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Click()
{
// XXX write me
return NS_OK;
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLInputElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX align
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHODIMP
nsHTMLInputElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX align
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX align
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsHTMLInputElement::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
@ -265,3 +313,221 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIHTMLContent
static nsGenericHTMLElement::EnumTable kInputTypeTable[] = {
{ "browse", NS_FORM_BROWSE }, // XXX not valid html, but it is convient
{ "button", NS_FORM_INPUT_BUTTON },
{ "checkbox", NS_FORM_INPUT_CHECKBOX },
{ "file", NS_FORM_INPUT_FILE },
{ "hidden", NS_FORM_INPUT_HIDDEN },
{ "reset", NS_FORM_INPUT_RESET },
{ "image", NS_FORM_INPUT_IMAGE },
{ "password", NS_FORM_INPUT_PASSWORD },
{ "radio", NS_FORM_INPUT_RADIO },
{ "submit", NS_FORM_INPUT_SUBMIT },
{ "text", NS_FORM_INPUT_TEXT },
{ 0 }
};
NS_IMETHODIMP
nsHTMLInputElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
if (aAttribute == nsHTMLAtoms::type) {
nsGenericHTMLElement::EnumTable *table = kInputTypeTable;
while (nsnull != table->tag) {
if (aValue.EqualsIgnoreCase(table->tag)) {
aResult.SetIntValue(table->value, eHTMLUnit_Enumerated);
mType = table->value; // set the type of this input
return NS_CONTENT_ATTR_HAS_VALUE;
}
table++;
}
}
else if (aAttribute == nsHTMLAtoms::checked) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::width) {
nsGenericHTMLElement::ParseValueOrPercent(aValue, aResult,
eHTMLUnit_Pixel);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::height) {
nsGenericHTMLElement::ParseValueOrPercent(aValue, aResult,
eHTMLUnit_Pixel);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::maxlength) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::size) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::tabindex) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::align) {
if (nsGenericHTMLElement::ParseFormAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHODIMP
nsHTMLInputElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
if (aAttribute == nsHTMLAtoms::type) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::EnumValueToString(aValue, kInputTypeTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::FormAlignValueToString(aValue, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
aAttributes->GetAttribute(nsHTMLAtoms::type, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
switch (value.GetIntValue()) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
{
float p2t = aPresContext->GetPixelsToTwips();
nscoord pad = NSIntPixelsToTwips(3, p2t);
// add left and right padding around the radio button via css
nsStyleSpacing* spacing = (nsStyleSpacing*) aContext->GetMutableStyleData(eStyleStruct_Spacing);
if (eStyleUnit_Null == spacing->mMargin.GetLeftUnit()) {
nsStyleCoord left(pad);
spacing->mMargin.SetLeft(left);
}
if (eStyleUnit_Null == spacing->mMargin.GetRightUnit()) {
nsStyleCoord right(NSIntPixelsToTwips(5, p2t));
spacing->mMargin.SetRight(right);
}
// add bottom padding if backward mode
// XXX why isn't this working?
nsCompatibility mode;
aPresContext->GetCompatibilityMode(mode);
if (eCompatibility_NavQuirks == mode) {
if (eStyleUnit_Null == spacing->mMargin.GetBottomUnit()) {
nsStyleCoord bottom(pad);
spacing->mMargin.SetBottom(bottom);
}
}
break;
}
case NS_FORM_INPUT_IMAGE:
{
// Apply the image border as well. For form elements the color is
// always forced to blue.
static nscolor blue[4] = {
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255)
};
nsGenericHTMLElement::MapImageBorderAttributesInto(aAttributes, aContext, aPresContext, blue);
nsGenericHTMLElement::MapImageAttributesInto(aAttributes, aContext, aPresContext);
break;
}
}
}
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsHTMLInputElement::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
// nsIFormControl
// 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
nsHTMLInputElement::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_IMETHODIMP
nsHTMLInputElement::GetType(PRInt32* aType)
{
if (aType) {
*aType = mType;
return NS_OK;
} else {
return NS_FORM_NOTOK;
}
}
NS_IMETHODIMP
nsHTMLInputElement::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
}
return NS_OK;
}

Просмотреть файл

@ -17,6 +17,7 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +27,21 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIDOMText.h"
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
class nsHTMLOptionElement : public nsIDOMHTMLOptionElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
//public nsIFormControl
{
public:
nsHTMLOptionElement(nsIAtom* aTag);
@ -82,6 +91,7 @@ public:
protected:
nsGenericHTMLContainerElement mInner;
nsIForm* mForm;
};
nsresult
@ -102,29 +112,56 @@ nsHTMLOptionElement::nsHTMLOptionElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mForm = nsnull;
}
nsHTMLOptionElement::~nsHTMLOptionElement()
{
if (mForm) {
NS_RELEASE(mForm);
}
}
NS_IMPL_ADDREF(nsHTMLOptionElement)
// ISupports
NS_IMPL_RELEASE(nsHTMLOptionElement)
NS_IMETHODIMP
nsHTMLOptionElement::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
nsHTMLOptionElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLOptionElementIID)) {
nsIDOMHTMLOptionElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLOptionElement*) this;
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFormControlIID)) {
*aInstancePtr = (void*)(nsIFormControl*) this;
mRefCnt++;
return NS_OK;
}
return NS_NOINTERFACE;
}
// the option has a ref (not ref counted) to the form, but not vice versa. The form can get to the
// options via the select.
NS_IMETHODIMP_(nsrefcnt)
nsHTMLOptionElement::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else {
return mRefCnt;
}
}
nsresult
nsHTMLOptionElement::CloneNode(nsIDOMNode** aReturn)
{
@ -139,12 +176,30 @@ nsHTMLOptionElement::CloneNode(nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLOptionElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;/* XXX */
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLOptionElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
if (nsnull == aForm) {
mForm = nsnull;
return NS_OK;
} else {
NS_IF_RELEASE(mForm);
return aForm->QueryInterface(kIFormIID, (void**)&mForm);
}
}
NS_IMPL_BOOL_ATTR(nsHTMLOptionElement, DefaultSelected, defaultselected, eSetAttrNotify_None)
NS_IMPL_STRING_ATTR(nsHTMLOptionElement, Text, text, eSetAttrNotify_Render)
NS_IMPL_INT_ATTR(nsHTMLOptionElement, Index, index, eSetAttrNotify_None)
NS_IMPL_BOOL_ATTR(nsHTMLOptionElement, Disabled, disabled, eSetAttrNotify_Render)
NS_IMPL_STRING_ATTR(nsHTMLOptionElement, Label, label, eSetAttrNotify_Render)
@ -156,7 +211,14 @@ nsHTMLOptionElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::selected) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::disabled) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -165,7 +227,6 @@ nsHTMLOptionElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -174,7 +235,6 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX write me
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
@ -196,3 +256,29 @@ nsHTMLOptionElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
NS_IMETHODIMP
nsHTMLOptionElement::GetText(nsString& aText)
{
aText.SetLength(0);
nsIDOMNode* node = nsnull;
nsresult result = mInner.GetFirstChild(&node);
if ((NS_OK == result) && node) {
nsIDOMText* domText = nsnull;
result = node->QueryInterface(kIDOMTextIID, (void**)&domText);
if ((NS_OK == result) && domText) {
result = domText->GetData(aText);
aText.CompressWhitespace(PR_TRUE, PR_TRUE);
NS_RELEASE(domText);
}
NS_RELEASE(node);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionElement::SetText(const nsString& aText)
{
// XXX write me
return NS_OK;
}

Просмотреть файл

@ -17,6 +17,10 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +30,48 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIWidget.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLAttributes.h"
#include "nsIDOMHTMLOptionElement.h"
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
class nsHTMLSelectElement;
// nsOptionList
class nsOptionList : public nsIDOMHTMLCollection, public nsIScriptObjectOwner {
public:
nsOptionList();
nsOptionList(nsIDOMHTMLCollection* aCollection);
virtual ~nsOptionList();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
NS_IMETHOD ResetScriptObject();
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
nsVoidArray& GetElements() { return mElements; }
void Clear();
private:
nsVoidArray mElements;
void* mScriptObject;
};
class nsHTMLSelectElement : public nsIDOMHTMLSelectElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
{
public:
nsHTMLSelectElement(nsIAtom* aTag);
@ -90,10 +129,24 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init();
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
nsIForm* mForm;
nsOptionList* mOptions;
};
// nsHTMLSelectElement
// construction, destruction
nsresult
NS_NewHTMLSelectElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -112,29 +165,66 @@ nsHTMLSelectElement::nsHTMLSelectElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mOptions = nsnull;
mForm = nsnull;
mWidget = nsnull;
}
nsHTMLSelectElement::~nsHTMLSelectElement()
{
NS_IF_RELEASE(mWidget);
if (nsnull != mForm) {
// prevent mForm from decrementing its ref count on us
mForm->RemoveElement(this, PR_FALSE);
NS_RELEASE(mForm);
}
NS_IF_RELEASE(mOptions);
}
NS_IMPL_ADDREF(nsHTMLSelectElement)
// ISupports
NS_IMPL_RELEASE(nsHTMLSelectElement)
NS_IMETHODIMP
nsHTMLSelectElement::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
nsHTMLSelectElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLSelectElementIID)) {
nsIDOMHTMLSelectElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLSelectElement*)this;
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFormControlIID)) {
*aInstancePtr = (void*)(nsIFormControl*)this;
mRefCnt++;
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLSelectElement::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else if ((1 == mRefCnt) && mForm) {
mRefCnt = 0;
delete this;
return 0;
} else {
return mRefCnt;
}
}
// nsIDOMHTMLSelectElement
nsresult
nsHTMLSelectElement::CloneNode(nsIDOMNode** aReturn)
{
@ -147,29 +237,78 @@ nsHTMLSelectElement::CloneNode(nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
nsHTMLSelectElement::Add(nsIDOMHTMLElement* aElement, nsIDOMHTMLElement* aBefore)
{
*aForm = nsnull;/* XXX */
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::Remove(PRInt32 aIndex)
{
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
// 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
nsHTMLSelectElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
return NS_OK;
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_IMETHODIMP
nsHTMLSelectElement::GetOptions(nsIDOMHTMLCollection** aValue)
{
*aValue = nsnull;/* XXX */
if (!mOptions) {
Init();
}
NS_ADDREF(mOptions);
*aValue = mOptions;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetOptions(nsIDOMHTMLCollection* aValue)
{
return NS_OK;
if (mOptions) {
mOptions->Clear();
NS_RELEASE(mOptions);
}
mOptions = new nsOptionList(aValue);
NS_ADDREF(mOptions);
return NS_OK;
}
NS_IMPL_STRING_ATTR(nsHTMLSelectElement, Type, type, eSetAttrNotify_Restart)
@ -183,16 +322,24 @@ NS_IMPL_INT_ATTR(nsHTMLSelectElement, Size, size, eSetAttrNotify_Render)
NS_IMPL_INT_ATTR(nsHTMLSelectElement, TabIndex, tabindex, eSetAttrNotify_Render)
NS_IMETHODIMP
nsHTMLSelectElement::Blur()
nsHTMLSelectElement::Blur() // XXX not tested
{
// XXX write me
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::Focus()
{
// XXX write me
if (nsnull != mWidget) { // XXX not tested
mWidget->SetFocus();
}
return NS_OK;
}
@ -201,7 +348,27 @@ nsHTMLSelectElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::disabled) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::multiple) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::size) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::tabindex) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::align) {
if (nsGenericHTMLElement::ParseFormAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -210,7 +377,12 @@ nsHTMLSelectElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::FormAlignValueToString(aValue, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -219,7 +391,27 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX write me
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
@ -241,3 +433,210 @@ nsHTMLSelectElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIFormControl
NS_IMETHODIMP
nsHTMLSelectElement::GetType(PRInt32* aType)
{
if (aType) {
*aType = NS_FORM_SELECT;
return NS_OK;
} else {
return NS_FORM_NOTOK;
}
}
NS_IMETHODIMP
nsHTMLSelectElement::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
}
return NS_OK;
}
void GetOptionsRecurse(nsIContent* aContent, nsVoidArray& aOptions)
{
PRInt32 numChildren;
aContent->ChildCount(numChildren);
nsIContent* child = nsnull;
nsIDOMHTMLOptionElement* option = nsnull;
for (int i = 0; i < numChildren; i++) {
aContent->ChildAt(i, child);
if (child) {
nsresult result = child->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option);
if ((NS_OK == result) && option) {
aOptions.AppendElement(option); // keep the ref count
} else {
GetOptionsRecurse(child, aOptions);
}
NS_RELEASE(child);
}
}
}
NS_IMETHODIMP
nsHTMLSelectElement::Init()
{
if (mOptions) {
mOptions->Clear();
NS_RELEASE(mOptions);
}
mOptions = new nsOptionList();
NS_ADDREF(mOptions);
GetOptionsRecurse(this, mOptions->GetElements());
return NS_OK;
}
// nsOptionList implementation
// XXX this was modified form nsHTMLFormElement.cpp. We need a base class implementation
nsOptionList::nsOptionList()
{
mRefCnt = 0;
mScriptObject = nsnull;
}
nsOptionList::nsOptionList(nsIDOMHTMLCollection* aCollection)
{
mRefCnt = 0;
mScriptObject = nsnull;
if (aCollection) {
PRUint32 length = 0;
aCollection->GetLength(&length);
nsIDOMNode* node;
for (PRUint32 elemX = 0; elemX < length; elemX++) {
nsresult result = aCollection->Item(elemX, &node); // this assumes an ADDREF
if ((NS_OK == result) && node) {
nsIDOMHTMLOptionElement* option = nsnull;
result = node->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option);
if ((NS_OK == result) && option) {
mElements.AppendElement(node); // keep the node ref count
NS_RELEASE(option);
}
}
}
}
}
nsOptionList::~nsOptionList()
{
Clear();
}
nsresult nsOptionList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsOptionList)
NS_IMPL_RELEASE(nsOptionList)
nsresult nsOptionList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLCollection(aContext, (nsISupports *)(nsIDOMHTMLCollection *)this, nsnull, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsOptionList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
nsresult nsOptionList::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
// nsIDOMHTMLCollection interface
NS_IMETHODIMP
nsOptionList::GetLength(PRUint32* aLength)
{
*aLength = mElements.Count();
return NS_OK;
}
NS_IMETHODIMP
nsOptionList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
*aReturn = (nsIDOMNode*)mElements.ElementAt(aIndex);
NS_ADDREF(*aReturn);
return NS_OK;
}
NS_IMETHODIMP
nsOptionList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
PRUint32 count = mElements.Count();
nsresult result = NS_OK;
*aReturn = nsnull;
for (PRUint32 i = 0; i < count && *aReturn == nsnull; i++) {
nsIDOMHTMLOptionElement *option;
option = (nsIDOMHTMLOptionElement*)mElements.ElementAt(i);
if (nsnull != option) {
nsIContent *content;
result = option->QueryInterface(kIContentIID, (void **)&content);
if (NS_OK == result) {
nsAutoString name;
// XXX Should it be an EqualsIgnoreCase?
if (((content->GetAttribute("NAME", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name))) ||
((content->GetAttribute("ID", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name)))) {
result = option->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
NS_RELEASE(content);
}
NS_RELEASE(option);
}
}
return result;
}
void
nsOptionList::Clear()
{
PRUint32 numOptions = mElements.Count();
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = (nsIDOMHTMLOptionElement*)mElements.ElementAt(i);
NS_RELEASE(option);
}
mElements.Clear();
}

Просмотреть файл

@ -17,6 +17,9 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +29,21 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIWidget.h"
#include "nsITextWidget.h"
#include "nsIHTMLAttributes.h"
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
class nsHTMLTextAreaElement : public nsIDOMHTMLTextAreaElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
{
public:
nsHTMLTextAreaElement(nsIAtom* aTag);
@ -85,8 +96,15 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
nsIForm* mForm;
};
nsresult
@ -107,29 +125,62 @@ nsHTMLTextAreaElement::nsHTMLTextAreaElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mForm = nsnull;
mWidget = nsnull;
}
nsHTMLTextAreaElement::~nsHTMLTextAreaElement()
{
NS_IF_RELEASE(mWidget);
if (nsnull != mForm) {
// prevent mForm from decrementing its ref count on us
mForm->RemoveElement(this, PR_FALSE);
NS_RELEASE(mForm);
}
}
NS_IMPL_ADDREF(nsHTMLTextAreaElement)
NS_IMPL_RELEASE(nsHTMLTextAreaElement)
NS_IMETHODIMP
nsHTMLTextAreaElement::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
nsHTMLTextAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLTextAreaElementIID)) {
nsIDOMHTMLTextAreaElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLTextAreaElement*) this;
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFormControlIID)) {
*aInstancePtr = (void*)(nsIFormControl*) this;
mRefCnt++;
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLTextAreaElement::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else if ((1 == mRefCnt) && mForm) {
mRefCnt = 0;
delete this;
return 0;
} else {
return mRefCnt;
}
}
// nsIDOMHTMLTextAreaElement
nsresult
nsHTMLTextAreaElement::CloneNode(nsIDOMNode** aReturn)
{
@ -144,34 +195,73 @@ nsHTMLTextAreaElement::CloneNode(nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLTextAreaElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;/* XXX */
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
// 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
nsHTMLTextAreaElement::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_IMETHODIMP
nsHTMLTextAreaElement::Blur() // XXX not tested
{
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Blur()
nsHTMLTextAreaElement::Focus() // XXX not tested
{
// XXX write me
if (nsnull != mWidget) {
mWidget->SetFocus();
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Focus()
nsHTMLTextAreaElement::Select() // XXX not tested
{
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Select()
{
// XXX write me
if (nsnull != mWidget) {
nsITextWidget *textWidget;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
}
return NS_OK;
}
@ -189,7 +279,31 @@ nsHTMLTextAreaElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::align) {
if (nsGenericHTMLElement::ParseFormAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::disabled) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::cols) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::readonly) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::rows) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::tabindex) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -198,7 +312,12 @@ nsHTMLTextAreaElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::FormAlignValueToString(aValue, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -207,7 +326,26 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX write me
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
@ -229,3 +367,29 @@ nsHTMLTextAreaElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIFormControl
NS_IMETHODIMP
nsHTMLTextAreaElement::GetType(PRInt32* aType)
{
if (aType) {
*aType = NS_FORM_TEXTAREA;
return NS_OK;
} else {
return NS_FORM_NOTOK;
}
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
}
return NS_OK;
}

Просмотреть файл

@ -36,8 +36,9 @@
#include "nsIDOMText.h"
#include "nsHTMLForms.h"
#include "nsIFormManager.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIFormControl.h"
#include "nsIImageMap.h"
@ -48,6 +49,7 @@
#include "nsIFrame.h"
#include "nsIWebShell.h"
#include "nsIHTMLDocument.h"
// XXX Go through a factory for this one
#include "nsICSSParser.h"
@ -59,11 +61,16 @@ static NS_DEFINE_IID(kIDOMHTMLTitleElementIID, NS_IDOMHTMLTITLEELEMENT_IID);
#define XXX_ART_HACK 1
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
static NS_DEFINE_IID(kIHTMLContentIID, NS_IHTMLCONTENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kIHTTPUrlIID, NS_IHTTPURL_IID);
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
//----------------------------------------------------------------------
@ -174,7 +181,7 @@ public:
PRInt32 mInMonolithicContainer;
PRBool mDirty;
PRBool mLayoutStarted;
nsIFormManager* mCurrentForm;
nsIDOMHTMLFormElement* mCurrentForm;
nsIImageMap* mCurrentMap;
SinkContext** mContexts;
@ -236,8 +243,6 @@ public:
nsresult AddText(const nsString& aText);
nsresult FlushText(PRBool* aDidFlush = nsnull);
nsresult AddOptionText(const nsIParserNode& aNode);
void MaybeMarkSinkDirty();
HTMLContentSink* mSink;
@ -260,8 +265,6 @@ public:
PRInt32 mTextLength;
PRInt32 mTextSize;
nsIHTMLContent* mCurrentSelect;
nsIHTMLContent* mCurrentOption;
};
//----------------------------------------------------------------------
@ -449,13 +452,24 @@ AddAttributes(const nsIParserNode& aNode,
return NS_OK;
}
void SetForm(nsIHTMLContent* aContent, nsIDOMHTMLFormElement* aForm)
{
nsIFormControl* formControl = nsnull;
nsresult result = aContent->QueryInterface(kIFormControlIID, (void**)&formControl);
if ((NS_OK == result) && formControl) {
formControl->SetForm(aForm);
NS_RELEASE(formControl);
}
}
// XXX compare switch statement against nsHTMLTags.h's list
static nsresult
MakeContentObject(nsHTMLTag aNodeType,
nsIAtom* aAtom,
nsIFormManager* aForm,
nsIDOMHTMLFormElement* aForm,
nsIWebShell* aWebShell,
nsIHTMLContent** aResult)
nsIHTMLContent** aResult,
const nsString* aContent = nsnull)
{
nsresult rv = NS_OK;
switch (aNodeType) {
@ -512,7 +526,11 @@ MakeContentObject(nsHTMLTag aNodeType,
rv = NS_NewHTMLFontElement(aResult, aAtom);
break;
case eHTMLTag_form:
rv = NS_NewHTMLFormElement(aResult, aAtom);
// the form was already created
*aResult = nsnull;
if (aForm) {
rv = aForm->QueryInterface(kIHTMLContentIID, (void**)aResult);
}
break;
case eHTMLTag_frame:
rv = NS_NewHTMLFrameElement(aResult, aAtom);
@ -542,6 +560,7 @@ MakeContentObject(nsHTMLTag aNodeType,
break;
case eHTMLTag_input:
rv = NS_NewHTMLInputElement(aResult, aAtom);
SetForm(*aResult, aForm);
break;
case eHTMLTag_isindex:
rv = NS_NewHTMLIsIndexElement(aResult, aAtom);
@ -577,7 +596,7 @@ MakeContentObject(nsHTMLTag aNodeType,
rv = NS_NewHTMLOptGroupElement(aResult, aAtom);
break;
case eHTMLTag_option:
rv = NS_NewHTMLOption(aResult, aAtom);/* XXX old style */
rv = NS_NewHTMLOptionElement(aResult, aAtom);
break;
case eHTMLTag_p:
rv = NS_NewHTMLParagraphElement(aResult, aAtom);
@ -595,7 +614,8 @@ MakeContentObject(nsHTMLTag aNodeType,
rv = NS_NewHTMLScriptElement(aResult, aAtom);
break;
case eHTMLTag_select:
rv = NS_NewHTMLSelect(aResult, aAtom, aForm);/* XXX old style */
rv = NS_NewHTMLSelectElement(aResult, aAtom);
SetForm(*aResult, aForm);
break;
case eHTMLTag_spacer:
rv = NS_NewHTMLSpacerElement(aResult, aAtom);
@ -617,6 +637,17 @@ MakeContentObject(nsHTMLTag aNodeType,
break;
case eHTMLTag_textarea:
rv = NS_NewHTMLTextAreaElement(aResult, aAtom);
// XXX why is textarea not a container. If it were, this code would not be necessary
// If the text area has some content, set it
if (aContent && (aContent->Length() > 0)) {
nsIDOMHTMLTextAreaElement* taElem;
rv = (*aResult)->QueryInterface(kIDOMHTMLTextAreaElementIID, (void **)&taElem);
if ((NS_OK == rv) && taElem) {
taElem->SetDefaultValue(*aContent);
NS_RELEASE(taElem);
}
}
SetForm(*aResult, aForm);
break;
case eHTMLTag_title:
rv = NS_NewHTMLTitleElement(aResult, aAtom);
@ -634,13 +665,44 @@ MakeContentObject(nsHTMLTag aNodeType,
return rv;
}
#if 0
// XXX is this logic needed by nsDOMHTMLOptionElement?
void
GetOptionText(const nsIParserNode& aNode, nsString& aText)
{
aText.SetLength(0);
switch (aNode.GetTokenType()) {
case eToken_text:
case eToken_whitespace:
case eToken_newline:
aText.Append(aNode.GetText());
break;
case eToken_entity:
{
nsAutoString tmp2("");
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp2);
if (unicode < 0) {
aText.Append(aNode.GetText());
} else {
aText.Append(tmp2);
}
}
break;
}
nsAutoString x;
char* y = aText.ToNewCString();
printf("foo");
}
#endif
/**
* Factory subroutine to create all of the html content objects.
*/
static nsresult
CreateContentObject(const nsIParserNode& aNode,
nsHTMLTag aNodeType,
nsIFormManager* aForm,
nsIDOMHTMLFormElement* aForm,
nsIWebShell* aWebShell,
nsIHTMLContent** aResult)
{
@ -660,7 +722,7 @@ CreateContentObject(const nsIParserNode& aNode,
// Make the content object
nsresult rv;
// XXX right now this code is here because we need aNode to create
// images, textareas and input form elements. As soon as all of the
// generic content code is in use, it can be moved up into
@ -720,69 +782,16 @@ CreateContentObject(const nsIParserNode& aNode,
rv = NS_NewHTMLImageElement(aResult, atom);
#endif /* XXX */
break;
case eHTMLTag_input:
{
nsAutoString val;
if (FindAttribute(aNode, "type", val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewHTMLInputSubmit(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewHTMLInputReset(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewHTMLInputButton(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewHTMLInputCheckbox(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewHTMLInputFile(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewHTMLInputHidden(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewHTMLInputImage(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewHTMLInputPassword(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewHTMLInputRadio(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewHTMLInputText(aResult, atom, aForm);
}
else {
rv = NS_NewHTMLInputText(aResult, atom, aForm);
}
}
else {
rv = NS_NewHTMLInputText(aResult, atom, aForm);
}
}
break;
case eHTMLTag_textarea:
{
const nsString& content = aNode.GetSkippedContent();
rv = NS_NewHTMLTextArea(aResult, atom, aForm);
if (NS_OK == rv) {
// If the text area has some content, give it to it now
if (content.Length() > 0) {
nsIFormControl* ctrl;
rv = (*aResult)->QueryInterface(kIFormControlIID, (void **)&ctrl);
if (NS_OK == rv) {
ctrl->SetContent(content);
NS_RELEASE(ctrl);
}
}
}
}
break;
default:
rv = MakeContentObject(aNodeType, atom, aForm, aWebShell, aResult);
break;
{
// XXX why is textarea not a container?
nsAutoString content;
if (eHTMLTag_textarea == aNodeType) {
content = aNode.GetSkippedContent();
}
rv = MakeContentObject(aNodeType, atom, aForm, aWebShell, aResult, &content);
break;
}
}
NS_RELEASE(atom);
@ -822,8 +831,6 @@ SinkContext::SinkContext(HTMLContentSink* aSink)
mText = nsnull;
mTextLength = 0;
mTextSize = 0;
mCurrentOption = nsnull;
mCurrentSelect = nsnull;
}
SinkContext::~SinkContext()
@ -837,8 +844,6 @@ SinkContext::~SinkContext()
if (nsnull != mText) {
delete [] mText;
}
NS_IF_RELEASE(mCurrentOption);
NS_IF_RELEASE(mCurrentSelect);
}
nsresult
@ -923,16 +928,6 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
case eHTMLTag_a:
mSink->ProcessATag(aNode, content);
break;
case eHTMLTag_select:
NS_IF_RELEASE(mCurrentSelect);
mCurrentSelect = content;
NS_IF_ADDREF(content);
break;
case eHTMLTag_option:
NS_IF_RELEASE(mCurrentOption);
mCurrentOption = content;
NS_IF_ADDREF(content);
break;
case eHTMLTag_table:
mSink->mInMonolithicContainer++;
break;
@ -964,12 +959,6 @@ SinkContext::CloseContainer(const nsIParserNode& aNode)
// Special handling for certain tags
switch (nodeType) {
case eHTMLTag_option:
NS_IF_RELEASE(mCurrentOption);
break;
case eHTMLTag_select:
NS_IF_RELEASE(mCurrentSelect);
break;
case eHTMLTag_table:
mSink->mInMonolithicContainer--;
break;
@ -989,12 +978,6 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
nsresult rv = NS_OK;
// XXX temporary hack until option layout code can find content
// the proper way.
if (eHTMLTag_option == mStack[mStackPos-1].mType) {
return AddOptionText(aNode);
}
switch (aNode.GetTokenType()) {
case eToken_start:
{
@ -1181,44 +1164,6 @@ SinkContext::FlushText(PRBool* aDidFlush)
return rv;
}
nsresult
SinkContext::AddOptionText(const nsIParserNode& aNode)
{
if ((nsnull != mCurrentSelect) && (nsnull != mCurrentOption)) {
nsIFormControl* control = nsnull;
mCurrentOption->QueryInterface(kIFormControlIID, (void **)&control);
if (nsnull != control) {
// Get current content and append on the new content
nsAutoString currentText;
control->GetContent(currentText);
switch (aNode.GetTokenType()) {
case eToken_text:
case eToken_whitespace:
case eToken_newline:
currentText.Append(aNode.GetText());
break;
case eToken_entity:
{
nsAutoString tmp2("");
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp2);
if (unicode < 0) {
currentText.Append(aNode.GetText());
} else {
currentText.Append(tmp2);
}
}
break;
}
control->SetContent(currentText);
NS_RELEASE(control);
}
}
return NS_OK;
}
//----------------------------------------------------------------------
nsresult
NS_NewHTMLContentSink(nsIHTMLContentSink** aResult,
@ -1610,7 +1555,6 @@ HTMLContentSink::CloseBody(const nsIParserNode& aNode)
return NS_OK;
}
// XXX add code to place form into the content model
NS_IMETHODIMP
HTMLContentSink::OpenForm(const nsIParserNode& aNode)
{
@ -1622,44 +1566,28 @@ HTMLContentSink::OpenForm(const nsIParserNode& aNode)
// Close out previous form if it's there
NS_IF_RELEASE(mCurrentForm);
// Create new form
// set the current form
nsAutoString tmp("FORM");
nsIAtom* atom = NS_NewAtom(tmp);
if (nsnull == atom) {
return NS_ERROR_OUT_OF_MEMORY;
nsIHTMLContent* iContent = nsnull;
nsresult rv = NS_NewHTMLFormElement(&iContent, atom);
if ((NS_OK == rv) && iContent) {
iContent->QueryInterface(kIDOMHTMLFormElementIID, (void**)&mCurrentForm);
NS_RELEASE(iContent);
}
nsresult rv = NS_NewHTMLForm(&mCurrentForm, atom);
NS_RELEASE(atom);
if (NS_OK == rv) {
// XXX replace with AddAttributes when form's implement nsIHTMLContent
// Add tag attributes to the form; we can't use AddAttributes
// because mCurrentForm is not an nsIHTMLContent (yet).
nsIScriptContextOwner* sco = mDocument->GetScriptContextOwner();
nsAutoString k, v;
PRInt32 ac = aNode.GetAttributeCount();
for (PRInt32 i = 0; i < ac; i++) {
// Get upper-cased key
const nsString& key = aNode.GetKeyAt(i);
k.SetLength(0);
k.Append(key);
k.ToUpperCase();
AddLeaf(aNode);
// Get value and remove mandatory quotes
GetAttributeValueAt(aNode, i, v, sco);
mCurrentForm->SetAttribute(k, v);
}
NS_IF_RELEASE(sco);
// XXX Temporary code till forms become real content
// Add the form to the document
((nsHTMLDocument*)mDocument)->AddForm(mCurrentForm);
nsIContent *content;
if (NS_OK == mCurrentForm->QueryInterface(kIContentIID, (void **)&content)) {
content->SetDocument(mDocument);
NS_RELEASE(content);
}
}
// 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);
// }
//}
return NS_OK;
}

Просмотреть файл

@ -15,6 +15,7 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsHTMLDocument.h"
#include "nsIParser.h"
#include "nsIHTMLContentSink.h"
@ -31,6 +32,7 @@
#include "nsIDOMNode.h" // for Find
#include "nsIDOMElement.h"
#include "nsIDOMText.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIPostToServer.h"
#include "nsIStreamListener.h"
#include "nsIURL.h"
@ -88,7 +90,6 @@ nsHTMLDocument::nsHTMLDocument()
mEmbeds = nsnull;
mLinks = nsnull;
mAnchors = nsnull;
mForms = nsnull;
mNamedItems = nsnull;
mParser = nsnull;
nsHTMLAtoms::AddrefAtoms();
@ -108,27 +109,21 @@ nsHTMLDocument::nsHTMLDocument()
mParentStack = (nsIDOMNode**) new PRUint32[32];
mChildStack = (nsIDOMNode**) new PRUint32[32];
mBodyContent = nsnull;
mForms = nsnull;
}
nsHTMLDocument::~nsHTMLDocument()
{
// XXX Temporary code till forms become real content
PRInt32 i;
for (i = 0; i < mTempForms.Count(); i++) {
nsIFormManager *form = (nsIFormManager *)mTempForms.ElementAt(i);
if (nsnull != form) {
NS_RELEASE(form);
}
}
DeleteNamedItems();
NS_IF_RELEASE(mImages);
NS_IF_RELEASE(mApplets);
NS_IF_RELEASE(mEmbeds);
NS_IF_RELEASE(mLinks);
NS_IF_RELEASE(mAnchors);
NS_IF_RELEASE(mForms);
NS_IF_RELEASE(mAttrStyleSheet);
NS_IF_RELEASE(mAttrStyleSheet);
NS_IF_RELEASE(mStyleAttrStyleSheet);
NS_IF_RELEASE(mParser);
for (i = 0; i < mImageMaps.Count(); i++) {
@ -136,6 +131,10 @@ nsHTMLDocument::~nsHTMLDocument()
NS_RELEASE(map);
}
if (mForms) {
mForms->Reset();
NS_RELEASE(mForms);
}
// XXX don't bother doing this until the dll is unloaded???
// nsHTMLAtoms::ReleaseAtoms();
@ -337,41 +336,6 @@ NS_IMETHODIMP nsHTMLDocument::GetImageMap(const nsString& aMapName,
return 1;/* XXX NS_NOT_FOUND */
}
// XXX Temporary form methods. Forms will soon become actual content
// elements. For now, the document keeps a list of them.
NS_IMETHODIMP
nsHTMLDocument::AddForm(nsIFormManager *aForm)
{
NS_PRECONDITION(nsnull != aForm, "null ptr");
if (nsnull == aForm) {
return NS_ERROR_NULL_POINTER;
}
if (mTempForms.AppendElement(aForm)) {
NS_ADDREF(aForm);
return NS_OK;
}
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP_(PRInt32)
nsHTMLDocument::GetFormCount() const
{
return mTempForms.Count();
}
NS_IMETHODIMP
nsHTMLDocument::GetFormAt(PRInt32 aIndex, nsIFormManager **aForm) const
{
*aForm = (nsIFormManager *)mTempForms.ElementAt(aIndex);
if (nsnull != *aForm) {
NS_ADDREF(*aForm);
return NS_OK;
}
return 1;/* XXX NS_NOT_FOUND */
}
NS_IMETHODIMP nsHTMLDocument::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
@ -596,57 +560,6 @@ nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
return NS_OK;
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// XXX Temporary till form becomes real content
class nsTempFormContentList : public nsContentList {
public:
nsTempFormContentList(nsHTMLDocument *aDocument);
~nsTempFormContentList();
};
nsTempFormContentList::nsTempFormContentList(nsHTMLDocument *aDocument) : nsContentList(aDocument)
{
PRInt32 i, count = aDocument->GetFormCount();
for (i=0; i < count; i++) {
nsIFormManager *form;
if (NS_OK == aDocument->GetFormAt(i, &form)) {
nsIContent *content;
if (NS_OK == form->QueryInterface(kIContentIID, (void **)&content)) {
Add(content);
NS_RELEASE(content);
}
NS_RELEASE(form);
}
}
}
nsTempFormContentList::~nsTempFormContentList()
{
mDocument = nsnull;
}
NS_IMETHODIMP
nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
{
if (nsnull == mForms) {
mForms = new nsTempFormContentList(this);
if (nsnull == mForms) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mForms);
}
*aForms = (nsIDOMHTMLCollection *)mForms;
NS_ADDREF(mForms);
return NS_OK;
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PRBool
nsHTMLDocument::MatchAnchors(nsIContent *aContent)
{
@ -1006,19 +919,6 @@ nsHTMLDocument::NamedItem(const nsString& aName, nsIDOMElement** aReturn)
mNamedItems = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
PL_CompareValues, nsnull, nsnull);
RegisterNamedItems(mRootContent, PR_FALSE);
// XXX Need to do this until forms become real content
PRInt32 i, count = mTempForms.Count();
for (i = 0; i < count; i++) {
nsIFormManager *form = (nsIFormManager *)mTempForms.ElementAt(i);
if (NS_OK == form->QueryInterface(kIContentIID, (void **)&content)) {
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(name, value)) {
char *nameStr = value.ToNewCString();
PL_HashTableAdd(mNamedItems, nameStr, content);
}
NS_RELEASE(content);
}
}
}
char *str = aName.ToNewCString();
@ -1987,3 +1887,47 @@ NS_IMETHODIMP nsHTMLDocument::FindNext(const nsString &aSearchStr, PRBool aMatch
return NS_OK;
}
// forms related stuff
// XXX remove this if GetForms is sufficient
NS_IMETHODIMP
nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm)
{
NS_PRECONDITION(nsnull != aForm, "null ptr");
if (nsnull == aForm) {
return NS_ERROR_NULL_POINTER;
}
if (!mForms) {
nsIDOMHTMLCollection* forms = nsnull;
GetForms(&forms);
}
nsIContent* iContent = nsnull;
nsresult result = aForm->QueryInterface(kIContentIID, (void**)&iContent);
if ((NS_OK == result) && iContent) {
if (mForms->Add(iContent)) {
NS_RELEASE(iContent);
return NS_OK;
}
}
return result;
}
NS_IMETHODIMP
nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
{
if (nsnull == mForms) {
nsAutoString tag("form");
mForms = new nsContentList(this, tag);
if (nsnull == mForms) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
*aForms = (nsIDOMHTMLCollection *)mForms;
NS_ADDREF(mForms);
return NS_OK;
}

Просмотреть файл

@ -53,17 +53,6 @@ public:
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult);
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// XXX Temporary form methods. Forms will soon become actual content
// elements. For now, the document keeps a list of them.
NS_IMETHOD AddForm(nsIFormManager *aForm);
NS_IMETHOD_(PRInt32) GetFormCount() const;
NS_IMETHOD GetFormAt(PRInt32 aIndex, nsIFormManager **aForm) const;
// XXX
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aStyleSheet);
NS_IMETHOD GetDTDMode(nsDTDMode& aMode);
@ -100,6 +89,8 @@ public:
// nsIDOMHTMLDocument interface
NS_DECL_IDOMHTMLDOCUMENT
NS_DECL_IDOMNSHTMLDOCUMENT
// the following is not part of nsIDOMHTMLDOCUMENT but allows the content sink to add forms
NS_IMETHOD AddForm(nsIDOMHTMLFormElement* aForm);
// From nsIScriptObjectOwner interface, implemented by nsDocument
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
@ -163,7 +154,6 @@ protected:
nsIHTMLCSSStyleSheet* mStyleAttrStyleSheet;
nsDTDMode mDTDMode;
nsVoidArray mImageMaps;
nsVoidArray mTempForms; // XXX Temporary
nsContentList *mImages;
nsContentList *mApplets;

Просмотреть файл

@ -21,7 +21,8 @@
#include "nsISupports.h"
class nsIImageMap;
class nsString;
class nsIFormManager;
class nsIDOMHTMLCollection;
class nsIDOMHTMLFormElement;
class nsIHTMLStyleSheet;
/* b2a848b0-d0a9-11d1-89b1-006008911b81 */
@ -44,20 +45,13 @@ public:
NS_IMETHOD AddImageMap(nsIImageMap* aMap) = 0;
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult) = 0;
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// XXX Temporary form methods. Forms will soon become actual content
// elements. For now, the document keeps a list of them.
NS_IMETHOD AddForm(nsIFormManager *aForm) = 0;
NS_IMETHOD_(PRInt32) GetFormCount() const = 0;
NS_IMETHOD GetFormAt(PRInt32 aIndex, nsIFormManager **aForm) const = 0;
// XXX
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aStyleSheet) = 0;
NS_IMETHOD AddForm(nsIDOMHTMLFormElement* aForm) = 0;
NS_IMETHOD GetForms(nsIDOMHTMLCollection** aForms) = 0;
/**
* Access DTD compatibility mode for this document
*/

Просмотреть файл

@ -948,40 +948,40 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent,
nsAutoString val;
if (NS_OK == aContent->GetAttribute(nsAutoString("type"), val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewInputCheckboxFrame(aContent, aParentFrame, aFrame);
rv = NS_NewCheckboxControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewInputFileFrame(aContent, aParentFrame, aFrame);
rv = NS_NewFileControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewInputRadioFrame(aContent, aParentFrame, aFrame);
rv = NS_NewRadioControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
} else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
return rv;
@ -1177,10 +1177,10 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = CreateInputFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::textarea == aTag) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aNewFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::select == aTag) {
rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, aNewFrame);
rv = NS_NewSelectControlFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::applet == aTag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, aNewFrame);
@ -1195,6 +1195,9 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = NS_NewBodyFrame(aContent, aParentFrame, aNewFrame);
processChildren = PR_TRUE;
}
else if (nsHTMLAtoms::form == aTag) {
rv = NS_NewFormFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::frameset == aTag) {
rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, aNewFrame);
}

Просмотреть файл

@ -347,10 +347,6 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
PresShell::~PresShell()
{
mRefCnt = 99;/* XXX hack! get around re-entrancy bugs */
if (nsnull != mDocument) {
mDocument->DeleteShell(this);
NS_RELEASE(mDocument);
}
if (nsnull != mRootFrame) {
mRootFrame->DeleteFrame(*mPresContext);
}
@ -358,6 +354,10 @@ PresShell::~PresShell()
//Release mPresContext after mViewManager
NS_IF_RELEASE(mPresContext);
NS_IF_RELEASE(mStyleSet);
if (nsnull != mDocument) {
mDocument->DeleteShell(this);
NS_RELEASE(mDocument);
}
mRefCnt = 0;
}

Просмотреть файл

@ -153,7 +153,6 @@
#define NS_STYLE_CLIP_RIGHT_AUTO 0x40
#define NS_STYLE_CLIP_BOTTOM_AUTO 0x80
// XXX Peter, is this ok?
// FRAME/FRAMESET/IFRAME specific values including backward compatibility. Boolean values with
// the same meaning (e.g. 1 & yes) may need to be distinguished for correct mode processing
#define NS_STYLE_FRAME_YES 0

Просмотреть файл

@ -0,0 +1,314 @@
/* -*- 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 "nsFileControlFrame.h"
#include "nsButtonControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
#include "nsIFileWidget.h"
#include "nsITextWidget.h"
#include "nsWidgetsCID.h"
#include "nsRepository.h"
#include "nsIView.h"
#include "nsHTMLParts.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsHTMLParts.h"
#include "nsIFormControl.h"
// XXX make this pixels
#define CONTROL_SPACING 40
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
nsresult
NS_NewFileControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsFileControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsFileControlFrame::nsFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsHTMLContainerFrame(aContent, aParentFrame)
{
mTextFrame = nsnull;
mBrowseFrame = nsnull;
mFormFrame = nsnull;
}
nsFileControlFrame::~nsFileControlFrame()
{
}
nsresult
nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIFormControlFrameIID)) {
*aInstancePtr = (void*) ((nsIFormControlFrame*) this);
return NS_OK;
}
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
PRBool
nsFileControlFrame::IsSuccessful()
{
nsAutoString name;
return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name));
}
void
nsFileControlFrame::Reset()
{
if (mTextFrame) {
mTextFrame->Reset();
}
}
NS_IMETHODIMP
nsFileControlFrame::GetType(PRInt32* aType) const
{
*aType = NS_FORM_INPUT_FILE;
return NS_OK;
}
// XXX this should be removed when nsView exposes it
nsIWidget*
GetWindowTemp(nsIView *aView)
{
nsIWidget *window = nsnull;
nsIView *ancestor = aView;
while (nsnull != ancestor) {
ancestor->GetWidget(window);
if (nsnull != window) {
return window;
}
ancestor->GetParent(ancestor);
}
return nsnull;
}
// 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)
{
nsIView* textView;
mTextFrame->GetView(textView);
if (nsnull == textView) {
return;
}
nsIWidget* widget;
mTextFrame->GetWidget(&widget);
if (!widget) {
return;
}
nsITextWidget* textWidget;
nsresult result = widget->QueryInterface(kITextWidgetIID, (void**)&textWidget);
if (NS_OK != result) {
NS_RELEASE(widget);
return;
}
nsIView* parentView;
textView->GetParent(parentView);
nsIWidget* parentWidget = GetWindowTemp(parentView);
nsIFileWidget *fileWidget;
nsString title("FileWidget Title <here> mode = save");
nsRepository::CreateInstance(kCFileWidgetCID, nsnull, kIFileWidgetIID, (void**)&fileWidget);
nsString titles[] = {"all files"};
nsString filters[] = {"*.*"};
fileWidget->SetFilterList(1, titles, filters);
fileWidget->Create(parentWidget, title, eMode_load, nsnull, nsnull);
result = fileWidget->Show();
if (result) {
PRUint32 size;
nsString fileName;
fileWidget->GetFile(fileName);
textWidget->SetText(fileName,size);
}
NS_RELEASE(fileWidget);
NS_RELEASE(parentWidget);
NS_RELEASE(textWidget);
NS_RELEASE(widget);
}
void SetType(nsIHTMLContent* aElement, nsString& aValue)
{
nsIHTMLContent* iContent = nsnull;
nsresult result = aElement->QueryInterface(kIHTMLContentIID, (void**)&iContent);
if ((NS_OK == result) && iContent) {
iContent->SetAttribute("type", aValue, PR_FALSE);
NS_RELEASE(iContent);
}
}
NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
PRInt32 numChildren = LengthOf(mFirstChild);
nsIFrame* childFrame;
if (0 == numChildren) {
// XXX This code should move to Init(), someday when the frame construction
// changes are all done and Init() is always getting called...
nsIHTMLContent* text = nsnull;
nsIAtom* tag = NS_NewAtom("text");
NS_NewHTMLInputElement(&text, tag);
text->SetAttribute("type", "text", PR_FALSE);
NS_NewTextControlFrame(text, this, childFrame);
childFrame->SetStyleContext(&aPresContext, mStyleContext);
mTextFrame = (nsTextControlFrame*)childFrame;
mFirstChild = childFrame;
nsIHTMLContent* browse = nsnull;
tag = NS_NewAtom("browse");
NS_NewHTMLInputElement(&browse, tag);
browse->SetAttribute("type", "browse", PR_FALSE);
NS_NewButtonControlFrame(browse, this, childFrame);
((nsButtonControlFrame*)childFrame)->SetFileControlFrame(this);
mBrowseFrame = (nsButtonControlFrame*)childFrame;
childFrame->SetStyleContext(&aPresContext, mStyleContext);
mFirstChild->SetNextSibling(childFrame);
mChildCount = 2;
NS_RELEASE(text);
NS_RELEASE(browse);
}
nsSize maxSize = aReflowState.maxSize;
nsReflowMetrics desiredSize = aDesiredSize;
aDesiredSize.width = CONTROL_SPACING;
aDesiredSize.height = 0;
childFrame = mFirstChild;
nsPoint offset(0,0);
while (nsnull != childFrame) { // reflow, place, size the children
nsReflowState reflowState(childFrame, aReflowState, maxSize);
childFrame->WillReflow(aPresContext);
nsresult result = childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
nsRect rect(offset.x, offset.y, desiredSize.width, desiredSize.height);
childFrame->SetRect(rect);
maxSize.width -= desiredSize.width;
aDesiredSize.width += desiredSize.width;
aDesiredSize.height = desiredSize.height;
childFrame->GetNextSibling(childFrame);
offset.x += desiredSize.width + CONTROL_SPACING;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
PRIntn
nsFileControlFrame::GetSkipSides() const
{
return 0;
}
NS_IMETHODIMP
nsFileControlFrame::GetName(nsString* aResult)
{
nsresult result = NS_FORM_NOTOK;
if (mContent) {
nsIHTMLContent* formControl = nsnull;
result = mContent->QueryInterface(kIHTMLContentIID, (void**)&formControl);
if ((NS_OK == result) && formControl) {
nsHTMLValue value;
result = formControl->GetAttribute(nsHTMLAtoms::name, value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
if (eHTMLUnit_String == value.GetUnit()) {
value.GetStringValue(*aResult);
}
}
NS_RELEASE(formControl);
}
}
return result;
}
PRInt32
nsFileControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsFileControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
return PR_FALSE;
}
// use our name and the text widgets value
aNames[0] = name;
nsresult status = PR_FALSE;
nsIWidget* widget;
nsITextWidget* textWidget;
mTextFrame->GetWidget(&widget);
if (widget && (NS_OK == widget->QueryInterface(kITextWidgetIID, (void**)&textWidget))) {
PRUint32 actualSize;
textWidget->GetText(aValues[0], 0, actualSize);
aNumValues = 1;
NS_RELEASE(textWidget);
status = PR_TRUE;
}
NS_IF_RELEASE(widget);
return status;
}

Просмотреть файл

@ -16,9 +16,10 @@
* Reserved.
*/
#ifndef nsInputFrame_h___
#define nsInputFrame_h___
#ifndef nsFormControlFrame_h___
#define nsFormControlFrame_h___
#include "nsIFormControlFrame.h"
#include "nsIFormManager.h"
#include "nsHTMLContainer.h"
#include "nsISupports.h"
@ -29,6 +30,10 @@
class nsIView;
class nsIPresContext;
class nsStyleCoord;
class nsFormFrame;
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
/**
* Enumeration of possible mouse states used to detect mouse clicks
@ -67,21 +72,25 @@ struct nsInputDimensionSpec
};
/**
* nsInputFrame is the base class for frames of form controls. It
* nsFormControlFrame is the base class for frames of form controls. It
* provides a uniform way of creating widgets, resizing, and painting.
* @see nsLeafFrame and its base classes for more info
*/
class nsInputFrame : public nsLeafFrame {
typedef nsLeafFrame nsInputFrameSuper;
class nsFormControlFrame : public nsLeafFrame,
public nsIFormControlFrame
{
public:
/**
* Main constructor
* @param aContent the content representing this frame
* @param aParentFrame the parent frame
*/
nsInputFrame(nsIContent* aContent, nsIFrame* aParentFrame);
nsFormControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
static nscoord CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame,
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
static nscoord CalculateSize (nsIPresContext* aPresContext, nsFormControlFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowSize);
@ -94,9 +103,7 @@ public:
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD SetRect(const nsRect& aRect);
/**
/**
* Draw this frame within the context of a presentation context and rendering context
* @see nsIFrame::Paint
*/
@ -118,12 +125,6 @@ public:
// new behavior
nsFormRenderingMode GetMode() const;
/**
* Return true if the underlying form element is a hidden form element
*/
PRBool IsHidden();
/**
* Get the class id of the widget associated with this frame
* @return the class id
@ -136,13 +137,21 @@ public:
*/
virtual const nsIID& GetIID();
NS_IMETHOD GetType(PRInt32* aType) const;
NS_IMETHOD GetName(nsString* aName);
NS_IMETHOD GetValue(nsString* aName);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
/**
* Get the widget associated with this frame
* @param aView the view associated with the frame. It is a convience parm.
* @param aWidget the address of address of where the widget will be placed.
* This method doses an AddRef on the widget.
*/
virtual nsresult GetWidget(nsIView* aView, nsIWidget** aWidget);
nsresult GetWidget(nsIView* aView, nsIWidget** aWidget);
nsresult GetWidget(nsIWidget** aWidget);
/**
* Respond to a enter key being pressed
@ -158,7 +167,10 @@ public:
* Perform opertations after the widget associated with this frame has been
* created.
*/
virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual void Reset();
virtual PRBool IsSuccessful();
/**
* Perform opertations before the widget associated with this frame has been
@ -166,9 +178,9 @@ public:
*/
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
static nscoord GetTextSize(nsIPresContext& aContext, nsInputFrame* aFrame,
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
const nsString& aString, nsSize& aSize);
static nscoord GetTextSize(nsIPresContext& aContext, nsInputFrame* aFrame,
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize);
void GetWidgetSize(nsSize& aSize) const { aSize.width = mWidgetSize.width;
@ -181,22 +193,22 @@ public:
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(float aPixToTwip,
virtual nscoord GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
NS_IMETHOD GetSize(PRInt32* aSize) const;
NS_IMETHOD GetMaxLength(PRInt32* aSize);
virtual void SetClickPoint(nscoord aX, nscoord aY);
nsFormFrame* GetFormFrame() { return mFormFrame; }
virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; }
protected:
virtual ~nsInputFrame();
virtual ~nsFormControlFrame();
/**
* Return PR_TRUE if the bounds of this frame have been set
*/
PRBool BoundsAreSet();
void SetViewVisiblity(nsIPresContext* aPresContext, PRBool aShow);
/**
* Get the size that this frame would occupy without any constraints
* @param aPresContext the presentation context
* @param aDesiredSize the size desired by this frame, to be set by this method
@ -211,7 +223,7 @@ protected:
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
const void GetFont(nsIPresContext* aPresContext, nsFont& aFont);
NS_IMETHOD GetFont(nsIPresContext* aPresContext, nsFont& aFont);
/**
* Get the width and height of this control based on CSS
@ -223,12 +235,20 @@ protected:
const nsReflowState& aReflowState,
nsSize& aSize);
nscoord GetStyleDim(nsIPresContext& aPresContext, nscoord aMaxDim,
nscoord aMaxWidth, const nsStyleCoord& aCoord);
//nscoord GetStyleDim(nsIPresContext& aPresContext, nscoord aMaxDim,
// nscoord aMaxWidth, const nsStyleCoord& aCoord);
nsMouseState mLastMouseState;
nsSize mWidgetSize;
PRBool mDidInit;
nsIWidget* mWidget;
nsSize mWidgetSize;
PRBool mDidInit;
nsPoint mLastClickPoint;
nsFormFrame* mFormFrame;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
};
#endif

Просмотреть файл

@ -0,0 +1,374 @@
/* -*- 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 "nsTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsFont.h"
#include "nsDOMEvent.h"
#include "nsIFormControl.h"
#include "nsFormFrame.h"
#include "nsIContent.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID);
static NS_DEFINE_IID(kTextAreaCID, NS_TEXTAREA_CID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
nsresult
NS_NewTextControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsTextControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsTextControlFrame::nsTextControlFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsFormControlFrame(aContent, aParentFrame)
{
}
nsTextControlFrame::~nsTextControlFrame()
{
}
nscoord
nsTextControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(4, aPixToTwip);
}
nscoord
nsTextControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
// for a text area aInnerHeight is the height of one line
nscoord
nsTextControlFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
#ifdef XP_PC
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.40f);
} else {
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.25f);
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(10, aPixToTwip); // XXX this is probably wrong
#endif
}
nscoord
nsTextControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
#ifdef XP_PC
nscoord padding;
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
padding = (nscoord)(40 * aCharWidth / 100);
} else {
padding = (nscoord)(55 * aCharWidth / 100);
}
nscoord min = NSIntPixelsToTwips(3, aPixToTwip);
if (padding > min) {
return padding;
} else {
return min;
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(6, aPixToTwip); // XXX this is probably wrong
#endif
}
const nsIID&
nsTextControlFrame::GetIID()
{
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
return kITextAreaWidgetIID;
} else {
return kITextWidgetIID;
}
}
const nsIID&
nsTextControlFrame::GetCID()
{
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
return kTextAreaCID;
} else {
return kTextCID;
}
}
void
nsTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
{
if (mFormFrame && mFormFrame->CanSubmit(*this)) {
nsEventStatus mStatus = nsEventStatus_eIgnore;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mFormFrame->OnSubmit(&aPresContext, this);
}
}
void
nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
// get the css size and let the frame use or override it
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
nsSize size;
PRBool widthExplicit, heightExplicit;
PRInt32 ignore;
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
PRInt32 width;
if (NS_CONTENT_ATTR_HAS_VALUE != GetSize(&width)) {
width = 20;
}
// Nav Quirk!!
width += 1;
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
nsnull, width, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, textSpec, size,
widthExplicit, heightExplicit, ignore);
} else {
nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, nsnull, 20,
PR_FALSE, nsHTMLAtoms::rows, 1);
CalculateSize(aPresContext, this, styleSize, areaSpec, size,
widthExplicit, heightExplicit, ignore);
}
if (NS_FORM_TEXTAREA == type) {
float p2t = aPresContext->GetPixelsToTwips();
nscoord scrollbarWidth = GetScrollbarWidth(p2t);
if (!heightExplicit) {
size.height += scrollbarWidth;
}
if (!widthExplicit) {
size.width += scrollbarWidth;
}
}
aDesiredLayoutSize.width = size.width;
aDesiredLayoutSize.height = size.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height = aDesiredLayoutSize.height;
}
nsWidgetInitData*
nsTextControlFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
PRInt32 type;
GetType(&type);
nsTextWidgetInitData* data = nsnull;
if (NS_FORM_INPUT_PASSWORD == type) {
data = new nsTextWidgetInitData();
data->clipChildren = PR_TRUE;
data->mIsPassword = PR_TRUE;
}
return data;
}
NS_IMETHODIMP
nsTextControlFrame::GetText(nsString* aText)
{
nsresult result = NS_CONTENT_ATTR_NOT_THERE;
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_TEXT == type) {
nsIDOMHTMLInputElement* textElem = nsnull;
nsresult result = mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&textElem);
if ((NS_OK == result) && textElem) {
result = textElem->GetValue(*aText);
NS_RELEASE(textElem);
}
} else {
nsIDOMHTMLTextAreaElement* textArea = nsnull;
nsresult result = mContent->QueryInterface(kIDOMHTMLTextAreaElementIID, (void**)&textArea);
if ((NS_OK == result) && textArea) {
result = textArea->GetDefaultValue(*aText);
NS_RELEASE(textArea);
}
}
return result;
}
void
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
{
if (!mWidget) {
return;
}
PRInt32 type;
GetType(&type);
const nsStyleFont* fontStyle = (const nsStyleFont*)(mStyleContext->GetStyleData(eStyleStruct_Font));
mWidget->SetFont(fontStyle->mFixedFont);
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
PRUint32 ignore;
nsAutoString value;
GetText(&value);
nsITextAreaWidget* textArea = nsnull;
nsITextWidget* text = nsnull;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->SetText(value, ignore);
PRInt32 maxLength;
nsresult result = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != result) {
text->SetMaxTextLength(maxLength);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->SetText(value, ignore);
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
NS_RELEASE(textArea);
}
}
PRInt32
nsTextControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if (!mWidget) {
return PR_FALSE;
}
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) {
return PR_FALSE;
}
PRUint32 size;
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
aNames[0] = name;
aNumValues = 1;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(text);
return PR_TRUE;
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(textArea);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsTextControlFrame::Reset()
{
if (!mWidget) {
return;
}
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
nsAutoString value;
nsresult valStatus = GetText(&value);
PRUint32 size;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
text->SetText(value,size);
} else {
text->SetText("",size);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
textArea->SetText(value,size);
} else {
textArea->SetText("",size);
}
NS_RELEASE(textArea);
}
}

Просмотреть файл

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsTextControlFrame_h___
#define nsTextControlFrame_h___
#include "nsFormControlFrame.h"
class nsIContent;
class nsIFrame;
class nsIPresContext;
class nsTextControlFrame : public nsFormControlFrame {
public:
nsTextControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
NS_IMETHOD GetText(nsString* aValue);
virtual void EnterPressed(nsIPresContext& aPresContext) ;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
protected:
virtual ~nsTextControlFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
#endif

Просмотреть файл

@ -295,29 +295,39 @@ nsresult
NS_NewWBRFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
// forms
extern nsresult
NS_NewInputButtonFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewFormFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame,
NS_NewButtonControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputTextFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewTextControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewHTMLSelectFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewRadioControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewSelectControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
// bullet
extern nsresult
NS_NewBulletFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewBulletFrame(nsIContent* aContent, nsIFrame* aParentFrame,

Просмотреть файл

@ -295,29 +295,39 @@ nsresult
NS_NewWBRFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
// forms
extern nsresult
NS_NewInputButtonFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewFormFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame,
NS_NewButtonControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputTextFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewTextControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewHTMLSelectFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
NS_NewRadioControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewSelectControlFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
// bullet
extern nsresult
NS_NewBulletFrame(nsIContent* aContent, nsIFrame* aParentFrame,
nsIFrame*& aResult);
extern nsresult
NS_NewBulletFrame(nsIContent* aContent, nsIFrame* aParentFrame,

Просмотреть файл

@ -17,7 +17,7 @@
DEPTH = ../../..
DIRS = src
DIRS = public src
include $(DEPTH)/config/config.mk

Просмотреть файл

@ -17,6 +17,6 @@
DEPTH=..\..\..
DIRS=src
DIRS=src public
include <$(DEPTH)\layout\config\rules.mak>

Просмотреть файл

@ -0,0 +1,29 @@
#!gmake
#
# 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.
DEPTH=../../../..
EXPORTS = \
nsIFormControl.h \
nsIForm.h \
$(NULL)
MODULE = raptor
include $(DEPTH)/config/config.mk
include $(DEPTH)/config/rules.mk

Просмотреть файл

@ -0,0 +1,25 @@
#!nmake
#
# 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.
DEPTH=..\..\..\..
EXPORTS=nsIFormControl.h nsIForm.h
MODULE=raptor
include <$(DEPTH)\layout\config\rules.mak>

Просмотреть файл

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIForm_h___
#define nsIForm_h___
#include "nsISupports.h"
class nsIFormControl;
#define NS_FORM_METHOD_GET 0
#define NS_FORM_METHOD_POST 1
#define NS_FORM_ENCTYPE_URLENCODED 0
#define NS_FORM_ENCTYPE_MULTIPART 1
// IID for the nsIFormManager interface
#define NS_IFORM_IID \
{ 0xb7e94510, 0x4c19, 0x11d2, \
{ 0x80, 0x3f, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
/**
* This interface provides a complete set of methods dealing with elements which
* belong to a form element. When nsIDOMHTMLCollection allows write operations
**/
class nsIForm : public nsISupports {
public:
/**
* Add an element to end of this form's list of elements
* @param aElement the element to add
* @return NS_OK if the element was successfully added
*/
NS_IMETHOD AddElement(nsIFormControl* aElement) = 0;
/**
* Get the element at a specified index position
* @param aIndex the index
* @param aElement the element at that index
* @return NS_OK if there was an element at that position, -1 otherwise
*/
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const = 0;
/**
* Get the number of elements in this form
* @param aCount the number of elements
* @return NS_OK if there was an element at that position, -1 otherwise
*/
NS_IMETHOD GetElementCount(PRUint32* aCount) const = 0;
/**
* Remove an element from this form's list of elements
* @param aElement the element to remove
* @param aChildIsRef if PR_TRUE, the elements ref count will be decremented
* otherwise not. This is to facilitate circular references.
* @return NS_OK if the element was successfully removed.
*/
NS_IMETHOD RemoveElement(nsIFormControl* aElement,
PRBool aChildIsRef = PR_TRUE) = 0;
};
#endif /* nsIForm_h___ */

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIFormControl_h___
#define nsIFormControl_h___
#include "nsISupports.h"
class nsIDOMHTMLFormElement;
class nsIWidget;
#define NS_FORM_BROWSE 0
#define NS_FORM_BUTTON 1
#define NS_FORM_FIELDSET 2
#define NS_FORM_INPUT_BUTTON 3
#define NS_FORM_INPUT_CHECKBOX 4
#define NS_FORM_INPUT_FILE 5
#define NS_FORM_INPUT_HIDDEN 6
#define NS_FORM_INPUT_RESET 7
#define NS_FORM_INPUT_IMAGE 8
#define NS_FORM_INPUT_PASSWORD 9
#define NS_FORM_INPUT_RADIO 10
#define NS_FORM_INPUT_SUBMIT 11
#define NS_FORM_INPUT_TEXT 12
#define NS_FORM_OPTION 13
#define NS_FORM_OPTGROUP 14
#define NS_FORM_LEGEND 15
#define NS_FORM_SELECT 16
#define NS_FORM_TEXTAREA 17
#define NS_FORM_NOTOK 0xFFFFFFF7
#define NS_FORM_NOTSET 0xFFFFFFF7
#define NS_IFORMCONTROL_IID \
{ 0x282ff440, 0xcd7e, 0x11d1, \
{0x89, 0xad, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/**
* Interface which all form controls (e.g. buttons, checkboxes, text,
* radio buttons, select, etc) implement in addition to their dom specific interface.
**/
class nsIFormControl : public nsISupports {
public:
/**
* Get the form for this form control.
* @param aForm the form to get
* @return NS_OK
*/
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm) = 0;
/**
* Set the form for this form control.
* @param aForm the form
* @return NS_OK
*/
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm) = 0;
/**
* Get the type of this control
* @param aType the type to be returned
* @return NS_OK
*/
NS_IMETHOD GetType(PRInt32* aType) = 0;
NS_IMETHOD SetWidget(nsIWidget* aWidget) = 0;
NS_IMETHOD Init() = 0;
};
#endif /* nsIFormControl_h___ */

Просмотреть файл

@ -936,8 +936,8 @@ nsGenericHTMLElement::SetClassName(const nsString& aClassName)
nsresult
nsGenericHTMLElement::GetDocument(nsIDocument*& aResult) const
{
aResult = mDocument;
NS_IF_ADDREF(mDocument);
aResult = mDocument;
return NS_OK;
}
@ -2253,6 +2253,15 @@ static nsGenericHTMLElement::EnumTable kDivAlignTable[] = {
{ 0 }
};
static nsGenericHTMLElement::EnumTable kFormAlignTable[] = {
{ "left", NS_STYLE_TEXT_ALIGN_LEFT },
{ "right", NS_STYLE_TEXT_ALIGN_RIGHT },
{ "bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM },
{ "top", NS_STYLE_VERTICAL_ALIGN_TOP },
{ "middle", NS_STYLE_VERTICAL_ALIGN_MIDDLE },
{ 0 }
};
static nsGenericHTMLElement::EnumTable kFrameborderQuirksTable[] = {
{ "yes", NS_STYLE_FRAME_YES },
{ "no", NS_STYLE_FRAME_NO },
@ -2331,6 +2340,20 @@ nsGenericHTMLElement::AlignValueToString(const nsHTMLValue& aValue,
return EnumValueToString(aValue, kAlignTable, aResult);
}
PRBool
nsGenericHTMLElement::ParseFormAlignValue(const nsString& aString,
nsHTMLValue& aResult)
{
return ParseEnumValue(aString, kFormAlignTable, aResult);
}
PRBool
nsGenericHTMLElement::FormAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult)
{
return EnumValueToString(aValue, kFormAlignTable, aResult);
}
PRBool
nsGenericHTMLElement::TableHAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult)

Просмотреть файл

@ -230,6 +230,9 @@ public:
static PRBool ParseAlignValue(const nsString& aString, nsHTMLValue& aResult);
static PRBool ParseFormAlignValue(const nsString& aString,
nsHTMLValue& aResult);
static PRBool ParseDivAlignValue(const nsString& aString,
nsHTMLValue& aResult);
@ -248,6 +251,8 @@ public:
static PRBool AlignValueToString(const nsHTMLValue& aValue,
nsString& aResult);
static PRBool FormAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult);
static PRBool DivAlignValueToString(const nsHTMLValue& aValue,
nsString& aResult);

Просмотреть файл

@ -154,6 +154,7 @@ NS_IMPL_STRING_ATTR(nsHTMLButtonElement, AccessKey, accesskey, eSetAttrNotify_No
NS_IMPL_BOOL_ATTR(nsHTMLButtonElement, Disabled, disabled, eSetAttrNotify_Render)
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Name, name, eSetAttrNotify_Restart)
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Type, type, eSetAttrNotify_Restart)
NS_IMPL_INT_ATTR(nsHTMLButtonElement, TabIndex, tabindex, eSetAttrNotify_None)
NS_IMPL_STRING_ATTR(nsHTMLButtonElement, Value, value, eSetAttrNotify_Render)
NS_IMETHODIMP

Просмотреть файл

@ -16,7 +16,12 @@
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIForm.h"
#include "nsIFormControl.h"
#include "nsIFormManager.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMNSHTMLFormElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +31,25 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
#include "nsIFrame.h"
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kIFormManagerIID, NS_IFORMMANAGER_IID);
static NS_DEFINE_IID(kIDOMNSHTMLFormElementIID, NS_IDOMNSHTMLFORMELEMENT_IID);
class nsFormControlList;
// nsHTMLFormElement
class nsHTMLFormElement : public nsIDOMHTMLFormElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIForm
{
public:
nsHTMLFormElement(nsIAtom* aTag);
@ -78,10 +95,45 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIForm
NS_IMETHOD AddElement(nsIFormControl* aElement);
NS_IMETHOD GetElementAt(PRInt32 aIndex, nsIFormControl** aElement) const;
NS_IMETHOD GetElementCount(PRUint32* aCount) const;
NS_IMETHOD RemoveElement(nsIFormControl* aElement, PRBool aChildIsRef = PR_TRUE);
protected:
nsFormControlList* mControls;
nsGenericHTMLLeafElement mInner;
};
// nsFormControlList
class nsFormControlList : public nsIDOMHTMLCollection, public nsIScriptObjectOwner {
public:
nsFormControlList();
virtual ~nsFormControlList();
void Clear();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
NS_IMETHOD ResetScriptObject();
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
// Called to tell us that the form is going away and that we
// should drop our (non ref-counted) reference to it
void ReleaseForm();
void *mScriptObject;
nsVoidArray mElements;
};
// nsHTMLFormElement implementation
// construction, destruction
nsresult
NS_NewHTMLFormElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -100,29 +152,80 @@ nsHTMLFormElement::nsHTMLFormElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mControls = new nsFormControlList();
NS_ADDREF(mControls);
nsTraceRefcnt::Create((nsIForm*)this, "nsHTMLFormElement", __FILE__, __LINE__);
}
nsHTMLFormElement::~nsHTMLFormElement()
{
// set the controls to have no form
PRUint32 numControls;
GetElementCount(&numControls);
for (PRUint32 i = 0; i < numControls; i++) {
// avoid addref to child
nsIFormControl* control = (nsIFormControl*)mControls->mElements.ElementAt(i);
if (control) {
// it is assummed that passing in nsnull will not release formControl's previous form
control->SetForm(nsnull);
}
}
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__);
}
NS_IMPL_ADDREF(nsHTMLFormElement)
NS_IMPL_RELEASE(nsHTMLFormElement)
nsresult
// nsISupports
NS_IMETHODIMP
nsHTMLFormElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLFormElementIID)) {
nsIDOMHTMLFormElement* tmp = this;
*aInstancePtr = (void*) tmp;
mRefCnt++;
if (aIID.Equals(kIFormIID)) {
*aInstancePtr = (void*)(nsIForm*)this;
AddRef();
return NS_OK;
}
else if (aIID.Equals(kIDOMHTMLFormElementIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLFormElement*)this;
AddRef();
return NS_OK;
}
else if (aIID.Equals(kIDOMNSHTMLFormElementIID)) {
*aInstancePtr = (void*)(nsIDOMNSHTMLFormElement*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsHTMLFormElement::AddRef(void)
{
nsTraceRefcnt::AddRef((nsIForm*)this, mRefCnt+1, __FILE__, __LINE__);
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLFormElement::Release()
{
nsTraceRefcnt::Release((nsIForm*)this, mRefCnt-1, __FILE__, __LINE__);
--mRefCnt;
PRUint32 numChildren;
GetElementCount(&numChildren);
if ((int)mRefCnt == numChildren) {
mRefCnt = 0;
delete this;
return 0;
}
return mRefCnt;
}
// nsIDOMHTMLFormElement
nsresult
nsHTMLFormElement::CloneNode(nsIDOMNode** aReturn)
{
@ -135,9 +238,10 @@ nsHTMLFormElement::CloneNode(nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsHTMLFormElement::GetElements(nsIDOMHTMLCollection** aResult)
nsHTMLFormElement::GetElements(nsIDOMHTMLCollection** aElements)
{
// XXX write me
*aElements = mControls;
NS_ADDREF(mControls);
return NS_OK;
}
@ -154,26 +258,85 @@ NS_IMPL_STRING_ATTR(nsHTMLFormElement, Method, method, eSetAttrNotify_None)
NS_IMPL_STRING_ATTR(nsHTMLFormElement, Target, target, eSetAttrNotify_None)
NS_IMETHODIMP
nsHTMLFormElement::Reset()
nsHTMLFormElement::Submit()
{
// XXX
return NS_OK;
// XXX Need to do something special with mailto: or news: URLs
nsIDocument* doc = nsnull;
nsresult result = GetDocument(doc);
if ((NS_OK == result) && doc) {
nsIPresShell *shell = doc->GetShellAt(0);
if (nsnull != shell) {
nsIFrame* frame = shell->FindFrameWithContent(this);
if (frame) {
nsIFormManager* formMan = nsnull;
nsresult result = frame->QueryInterface(kIFormManagerIID, (void**)&formMan);
if ((NS_OK == result) && formMan) {
nsIPresContext *context = shell->GetPresContext();
if (nsnull != context) {
// XXX We're currently passing in null for the frame.
// It works for now, but might not always
// be correct. In the future, we might not need the
// frame to be passed to the link handler.
result = formMan->OnSubmit(context, nsnull);
NS_RELEASE(context);
}
}
}
NS_RELEASE(shell);
}
NS_RELEASE(doc);
}
return result;
}
NS_IMETHODIMP
nsHTMLFormElement::Submit()
nsHTMLFormElement::Reset()
{
// XXX
return NS_OK;
}
// XXX Need to do something special with mailto: or news: URLs
nsIDocument* doc = nsnull;
nsresult result = GetDocument(doc);
if ((NS_OK == result) && doc) {
nsIPresShell *shell = doc->GetShellAt(0);
if (nsnull != shell) {
nsIFrame* frame = shell->FindFrameWithContent(this);
if (frame) {
nsIFormManager* formMan = nsnull;
nsresult result = frame->QueryInterface(kIFormManagerIID, (void**)&formMan);
if ((NS_OK == result) && formMan) {
result = formMan->OnReset();
}
}
NS_RELEASE(shell);
}
}
return result;
}
static nsGenericHTMLElement::EnumTable kFormMethodTable[] = {
{ "get", NS_FORM_METHOD_GET },
{ "post", NS_FORM_METHOD_POST },
{ 0 }
};
static nsGenericHTMLElement::EnumTable kFormEnctypeTable[] = {
{ "multipart/form-data", NS_FORM_ENCTYPE_MULTIPART },
{ "application/x-www-form-urlencoded", NS_FORM_ENCTYPE_URLENCODED },
{ 0 }
};
NS_IMETHODIMP
nsHTMLFormElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::method) {
nsGenericHTMLElement::ParseEnumValue(aValue, kFormMethodTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::enctype) {
nsGenericHTMLElement::ParseEnumValue(aValue, kFormEnctypeTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -182,7 +345,18 @@ nsHTMLFormElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
if (aAttribute == nsHTMLAtoms::method) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::EnumValueToString(aValue, kFormMethodTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::enctype) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::EnumValueToString(aValue, kFormEnctypeTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -214,3 +388,166 @@ nsHTMLFormElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIForm
NS_IMETHODIMP
nsHTMLFormElement::GetElementCount(PRUint32* aCount) const
{
mControls->GetLength(aCount);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFormElement::GetElementAt(PRInt32 aIndex, nsIFormControl** aFormControl) const
{
*aFormControl = (nsIFormControl*) mControls->mElements.ElementAt(aIndex);
NS_IF_ADDREF(*aFormControl);
return NS_OK;
}
NS_IMETHODIMP
nsHTMLFormElement::AddElement(nsIFormControl* aChild)
{
PRBool rv = mControls->mElements.AppendElement(aChild);
if (rv) {
NS_ADDREF(aChild);
}
return rv;
}
NS_IMETHODIMP
nsHTMLFormElement::RemoveElement(nsIFormControl* aChild, PRBool aChildIsRef)
{
PRBool rv = mControls->mElements.RemoveElement(aChild);
if (rv && aChildIsRef) {
NS_RELEASE(aChild);
}
return rv;
}
// nsFormControlList implementation, this could go away if there were a lightweight collection implementation somewhere
nsFormControlList::nsFormControlList()
{
mRefCnt = 0;
mScriptObject = nsnull;
}
nsFormControlList::~nsFormControlList()
{
}
NS_IMETHODIMP
nsFormControlList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
void
nsFormControlList::Clear()
{
PRUint32 numElements = mElements.Count();
for (PRUint32 i = 0; i < numElements; i++) {
nsIFormControl* elem = (nsIFormControl*) mElements.ElementAt(i);
NS_IF_RELEASE(elem);
}
}
nsresult nsFormControlList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsFormControlList)
NS_IMPL_RELEASE(nsFormControlList)
nsresult nsFormControlList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLCollection(aContext, (nsISupports *)(nsIDOMHTMLCollection *)this, nsnull, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
nsresult nsFormControlList::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
// nsIDOMHTMLCollection interface
NS_IMETHODIMP
nsFormControlList::GetLength(PRUint32* aLength)
{
*aLength = mElements.Count();
return NS_OK;
}
NS_IMETHODIMP
nsFormControlList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(aIndex);
if (control) {
return control->QueryInterface(kIDOMNodeIID, (void**)aReturn); // keep the ref
}
*aReturn = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsFormControlList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
PRUint32 count = mElements.Count();
nsresult result = NS_OK;
*aReturn = nsnull;
for (PRUint32 i = 0; i < count && *aReturn == nsnull; i++) {
nsIFormControl *control = (nsIFormControl*)mElements.ElementAt(i);
if (nsnull != control) {
nsIContent *content;
result = control->QueryInterface(kIContentIID, (void **)&content);
if (NS_OK == result) {
nsAutoString name;
// XXX Should it be an EqualsIgnoreCase?
if (((content->GetAttribute("NAME", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name))) ||
((content->GetAttribute("ID", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name)))) {
result = control->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
NS_RELEASE(content);
}
}
}
return result;
}

Просмотреть файл

@ -17,6 +17,7 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -27,15 +28,24 @@
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIHTMLAttributes.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIWidget.h"
#include "nsITextWidget.h"
// XXX align=left, hspace, vspace, border? other nav4 attrs
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_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);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
class nsHTMLInputElement : public nsIDOMHTMLInputElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
{
public:
nsHTMLInputElement(nsIAtom* aTag);
@ -105,10 +115,21 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFormControl
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm);
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
protected:
nsGenericHTMLLeafElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
nsIForm* mForm;
PRInt32 mType;
};
// construction, destruction
nsresult
NS_NewHTMLInputElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -127,29 +148,70 @@ nsHTMLInputElement::nsHTMLInputElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mType = NS_FORM_INPUT_TEXT; // default value
mForm = nsnull;
mWidget = nsnull;
nsTraceRefcnt::Create((nsIFormControl*)this, "nsHTMLFormControlElement", __FILE__, __LINE__);
}
nsHTMLInputElement::~nsHTMLInputElement()
{
NS_IF_RELEASE(mWidget);
if (nsnull != mForm) {
// prevent mForm from decrementing its ref count on us
mForm->RemoveElement(this, PR_FALSE);
NS_RELEASE(mForm);
}
nsTraceRefcnt::Destroy((nsIFormControl*)this, __FILE__, __LINE__);
}
NS_IMPL_ADDREF(nsHTMLInputElement)
// nsISupports
NS_IMPL_RELEASE(nsHTMLInputElement)
NS_IMETHODIMP_(nsrefcnt)
nsHTMLInputElement::AddRef(void)
{
nsTraceRefcnt::AddRef((nsIFormControl*)this, mRefCnt+1, __FILE__, __LINE__);
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
NS_IMETHODIMP
nsHTMLInputElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLInputElementIID)) {
nsIDOMHTMLInputElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLInputElement*) 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;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLInputElement::Release()
{
nsTraceRefcnt::Release((nsIFormControl*)this, mRefCnt-1, __FILE__, __LINE__);
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else if ((1 == mRefCnt) && mForm) {
mRefCnt = 0;
delete this;
return 0;
} else {
return mRefCnt;
}
}
// nsIDOMHTMLInputElement
nsresult
nsHTMLInputElement::CloneNode(nsIDOMNode** aReturn)
{
@ -164,7 +226,14 @@ nsHTMLInputElement::CloneNode(nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLInputElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;/* XXX */
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
@ -195,66 +264,45 @@ nsHTMLInputElement::GetType(nsString& aValue)
NS_IMETHODIMP
nsHTMLInputElement::Blur()
{
// XXX write me
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Focus()
{
// XXX write me
if (nsnull != mWidget) {
mWidget->SetFocus();
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Select()
{
// XXX write me
if ((NS_FORM_INPUT_TEXT == mType) && (nsnull != mWidget)) {
nsITextWidget *textWidget;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::Click()
{
// XXX write me
return NS_OK;
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHTMLInputElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX align
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHODIMP
nsHTMLInputElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX align
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX align
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsHTMLInputElement::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLInputElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
@ -265,3 +313,221 @@ nsHTMLInputElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIHTMLContent
static nsGenericHTMLElement::EnumTable kInputTypeTable[] = {
{ "browse", NS_FORM_BROWSE }, // XXX not valid html, but it is convient
{ "button", NS_FORM_INPUT_BUTTON },
{ "checkbox", NS_FORM_INPUT_CHECKBOX },
{ "file", NS_FORM_INPUT_FILE },
{ "hidden", NS_FORM_INPUT_HIDDEN },
{ "reset", NS_FORM_INPUT_RESET },
{ "image", NS_FORM_INPUT_IMAGE },
{ "password", NS_FORM_INPUT_PASSWORD },
{ "radio", NS_FORM_INPUT_RADIO },
{ "submit", NS_FORM_INPUT_SUBMIT },
{ "text", NS_FORM_INPUT_TEXT },
{ 0 }
};
NS_IMETHODIMP
nsHTMLInputElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
if (aAttribute == nsHTMLAtoms::type) {
nsGenericHTMLElement::EnumTable *table = kInputTypeTable;
while (nsnull != table->tag) {
if (aValue.EqualsIgnoreCase(table->tag)) {
aResult.SetIntValue(table->value, eHTMLUnit_Enumerated);
mType = table->value; // set the type of this input
return NS_CONTENT_ATTR_HAS_VALUE;
}
table++;
}
}
else if (aAttribute == nsHTMLAtoms::checked) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::width) {
nsGenericHTMLElement::ParseValueOrPercent(aValue, aResult,
eHTMLUnit_Pixel);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::height) {
nsGenericHTMLElement::ParseValueOrPercent(aValue, aResult,
eHTMLUnit_Pixel);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::maxlength) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::size) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::tabindex) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::align) {
if (nsGenericHTMLElement::ParseFormAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return NS_CONTENT_ATTR_NOT_THERE;
}
NS_IMETHODIMP
nsHTMLInputElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
if (aAttribute == nsHTMLAtoms::type) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::EnumValueToString(aValue, kInputTypeTable, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::FormAlignValueToString(aValue, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
aAttributes->GetAttribute(nsHTMLAtoms::type, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
switch (value.GetIntValue()) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
{
float p2t = aPresContext->GetPixelsToTwips();
nscoord pad = NSIntPixelsToTwips(3, p2t);
// add left and right padding around the radio button via css
nsStyleSpacing* spacing = (nsStyleSpacing*) aContext->GetMutableStyleData(eStyleStruct_Spacing);
if (eStyleUnit_Null == spacing->mMargin.GetLeftUnit()) {
nsStyleCoord left(pad);
spacing->mMargin.SetLeft(left);
}
if (eStyleUnit_Null == spacing->mMargin.GetRightUnit()) {
nsStyleCoord right(NSIntPixelsToTwips(5, p2t));
spacing->mMargin.SetRight(right);
}
// add bottom padding if backward mode
// XXX why isn't this working?
nsCompatibility mode;
aPresContext->GetCompatibilityMode(mode);
if (eCompatibility_NavQuirks == mode) {
if (eStyleUnit_Null == spacing->mMargin.GetBottomUnit()) {
nsStyleCoord bottom(pad);
spacing->mMargin.SetBottom(bottom);
}
}
break;
}
case NS_FORM_INPUT_IMAGE:
{
// Apply the image border as well. For form elements the color is
// always forced to blue.
static nscolor blue[4] = {
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255)
};
nsGenericHTMLElement::MapImageBorderAttributesInto(aAttributes, aContext, aPresContext, blue);
nsGenericHTMLElement::MapImageAttributesInto(aAttributes, aContext, aPresContext);
break;
}
}
}
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsHTMLInputElement::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
// nsIFormControl
// 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
nsHTMLInputElement::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_IMETHODIMP
nsHTMLInputElement::GetType(PRInt32* aType)
{
if (aType) {
*aType = mType;
return NS_OK;
} else {
return NS_FORM_NOTOK;
}
}
NS_IMETHODIMP
nsHTMLInputElement::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
}
return NS_OK;
}

Просмотреть файл

@ -17,6 +17,7 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +27,21 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIDOMText.h"
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
class nsHTMLOptionElement : public nsIDOMHTMLOptionElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
//public nsIFormControl
{
public:
nsHTMLOptionElement(nsIAtom* aTag);
@ -82,6 +91,7 @@ public:
protected:
nsGenericHTMLContainerElement mInner;
nsIForm* mForm;
};
nsresult
@ -102,29 +112,56 @@ nsHTMLOptionElement::nsHTMLOptionElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mForm = nsnull;
}
nsHTMLOptionElement::~nsHTMLOptionElement()
{
if (mForm) {
NS_RELEASE(mForm);
}
}
NS_IMPL_ADDREF(nsHTMLOptionElement)
// ISupports
NS_IMPL_RELEASE(nsHTMLOptionElement)
NS_IMETHODIMP
nsHTMLOptionElement::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
nsHTMLOptionElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLOptionElementIID)) {
nsIDOMHTMLOptionElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLOptionElement*) this;
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFormControlIID)) {
*aInstancePtr = (void*)(nsIFormControl*) this;
mRefCnt++;
return NS_OK;
}
return NS_NOINTERFACE;
}
// the option has a ref (not ref counted) to the form, but not vice versa. The form can get to the
// options via the select.
NS_IMETHODIMP_(nsrefcnt)
nsHTMLOptionElement::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else {
return mRefCnt;
}
}
nsresult
nsHTMLOptionElement::CloneNode(nsIDOMNode** aReturn)
{
@ -139,12 +176,30 @@ nsHTMLOptionElement::CloneNode(nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLOptionElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;/* XXX */
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLOptionElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
if (nsnull == aForm) {
mForm = nsnull;
return NS_OK;
} else {
NS_IF_RELEASE(mForm);
return aForm->QueryInterface(kIFormIID, (void**)&mForm);
}
}
NS_IMPL_BOOL_ATTR(nsHTMLOptionElement, DefaultSelected, defaultselected, eSetAttrNotify_None)
NS_IMPL_STRING_ATTR(nsHTMLOptionElement, Text, text, eSetAttrNotify_Render)
NS_IMPL_INT_ATTR(nsHTMLOptionElement, Index, index, eSetAttrNotify_None)
NS_IMPL_BOOL_ATTR(nsHTMLOptionElement, Disabled, disabled, eSetAttrNotify_Render)
NS_IMPL_STRING_ATTR(nsHTMLOptionElement, Label, label, eSetAttrNotify_Render)
@ -156,7 +211,14 @@ nsHTMLOptionElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::selected) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::disabled) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -165,7 +227,6 @@ nsHTMLOptionElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -174,7 +235,6 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX write me
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
@ -196,3 +256,29 @@ nsHTMLOptionElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
NS_IMETHODIMP
nsHTMLOptionElement::GetText(nsString& aText)
{
aText.SetLength(0);
nsIDOMNode* node = nsnull;
nsresult result = mInner.GetFirstChild(&node);
if ((NS_OK == result) && node) {
nsIDOMText* domText = nsnull;
result = node->QueryInterface(kIDOMTextIID, (void**)&domText);
if ((NS_OK == result) && domText) {
result = domText->GetData(aText);
aText.CompressWhitespace(PR_TRUE, PR_TRUE);
NS_RELEASE(domText);
}
NS_RELEASE(node);
}
return result;
}
NS_IMETHODIMP
nsHTMLOptionElement::SetText(const nsString& aText)
{
// XXX write me
return NS_OK;
}

Просмотреть файл

@ -17,6 +17,10 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +30,48 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIWidget.h"
#include "nsHTMLAtoms.h"
#include "nsIHTMLAttributes.h"
#include "nsIDOMHTMLOptionElement.h"
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
class nsHTMLSelectElement;
// nsOptionList
class nsOptionList : public nsIDOMHTMLCollection, public nsIScriptObjectOwner {
public:
nsOptionList();
nsOptionList(nsIDOMHTMLCollection* aCollection);
virtual ~nsOptionList();
NS_DECL_ISUPPORTS
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
NS_IMETHOD SetScriptObject(void *aScriptObject);
NS_IMETHOD ResetScriptObject();
// nsIDOMHTMLCollection interface
NS_DECL_IDOMHTMLCOLLECTION
nsVoidArray& GetElements() { return mElements; }
void Clear();
private:
nsVoidArray mElements;
void* mScriptObject;
};
class nsHTMLSelectElement : public nsIDOMHTMLSelectElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
{
public:
nsHTMLSelectElement(nsIAtom* aTag);
@ -90,10 +129,24 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init();
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
nsIForm* mForm;
nsOptionList* mOptions;
};
// nsHTMLSelectElement
// construction, destruction
nsresult
NS_NewHTMLSelectElement(nsIHTMLContent** aInstancePtrResult, nsIAtom* aTag)
{
@ -112,29 +165,66 @@ nsHTMLSelectElement::nsHTMLSelectElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mOptions = nsnull;
mForm = nsnull;
mWidget = nsnull;
}
nsHTMLSelectElement::~nsHTMLSelectElement()
{
NS_IF_RELEASE(mWidget);
if (nsnull != mForm) {
// prevent mForm from decrementing its ref count on us
mForm->RemoveElement(this, PR_FALSE);
NS_RELEASE(mForm);
}
NS_IF_RELEASE(mOptions);
}
NS_IMPL_ADDREF(nsHTMLSelectElement)
// ISupports
NS_IMPL_RELEASE(nsHTMLSelectElement)
NS_IMETHODIMP
nsHTMLSelectElement::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
nsHTMLSelectElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLSelectElementIID)) {
nsIDOMHTMLSelectElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLSelectElement*)this;
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFormControlIID)) {
*aInstancePtr = (void*)(nsIFormControl*)this;
mRefCnt++;
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLSelectElement::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else if ((1 == mRefCnt) && mForm) {
mRefCnt = 0;
delete this;
return 0;
} else {
return mRefCnt;
}
}
// nsIDOMHTMLSelectElement
nsresult
nsHTMLSelectElement::CloneNode(nsIDOMNode** aReturn)
{
@ -147,29 +237,78 @@ nsHTMLSelectElement::CloneNode(nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
nsHTMLSelectElement::Add(nsIDOMHTMLElement* aElement, nsIDOMHTMLElement* aBefore)
{
*aForm = nsnull;/* XXX */
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::Remove(PRInt32 aIndex)
{
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
// 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
nsHTMLSelectElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
return NS_OK;
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_IMETHODIMP
nsHTMLSelectElement::GetOptions(nsIDOMHTMLCollection** aValue)
{
*aValue = nsnull;/* XXX */
if (!mOptions) {
Init();
}
NS_ADDREF(mOptions);
*aValue = mOptions;
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::SetOptions(nsIDOMHTMLCollection* aValue)
{
return NS_OK;
if (mOptions) {
mOptions->Clear();
NS_RELEASE(mOptions);
}
mOptions = new nsOptionList(aValue);
NS_ADDREF(mOptions);
return NS_OK;
}
NS_IMPL_STRING_ATTR(nsHTMLSelectElement, Type, type, eSetAttrNotify_Restart)
@ -183,16 +322,24 @@ NS_IMPL_INT_ATTR(nsHTMLSelectElement, Size, size, eSetAttrNotify_Render)
NS_IMPL_INT_ATTR(nsHTMLSelectElement, TabIndex, tabindex, eSetAttrNotify_Render)
NS_IMETHODIMP
nsHTMLSelectElement::Blur()
nsHTMLSelectElement::Blur() // XXX not tested
{
// XXX write me
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLSelectElement::Focus()
{
// XXX write me
if (nsnull != mWidget) { // XXX not tested
mWidget->SetFocus();
}
return NS_OK;
}
@ -201,7 +348,27 @@ nsHTMLSelectElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::disabled) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::multiple) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::size) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::tabindex) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::align) {
if (nsGenericHTMLElement::ParseFormAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -210,7 +377,12 @@ nsHTMLSelectElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::FormAlignValueToString(aValue, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -219,7 +391,27 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX write me
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
@ -241,3 +433,210 @@ nsHTMLSelectElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIFormControl
NS_IMETHODIMP
nsHTMLSelectElement::GetType(PRInt32* aType)
{
if (aType) {
*aType = NS_FORM_SELECT;
return NS_OK;
} else {
return NS_FORM_NOTOK;
}
}
NS_IMETHODIMP
nsHTMLSelectElement::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
}
return NS_OK;
}
void GetOptionsRecurse(nsIContent* aContent, nsVoidArray& aOptions)
{
PRInt32 numChildren;
aContent->ChildCount(numChildren);
nsIContent* child = nsnull;
nsIDOMHTMLOptionElement* option = nsnull;
for (int i = 0; i < numChildren; i++) {
aContent->ChildAt(i, child);
if (child) {
nsresult result = child->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option);
if ((NS_OK == result) && option) {
aOptions.AppendElement(option); // keep the ref count
} else {
GetOptionsRecurse(child, aOptions);
}
NS_RELEASE(child);
}
}
}
NS_IMETHODIMP
nsHTMLSelectElement::Init()
{
if (mOptions) {
mOptions->Clear();
NS_RELEASE(mOptions);
}
mOptions = new nsOptionList();
NS_ADDREF(mOptions);
GetOptionsRecurse(this, mOptions->GetElements());
return NS_OK;
}
// nsOptionList implementation
// XXX this was modified form nsHTMLFormElement.cpp. We need a base class implementation
nsOptionList::nsOptionList()
{
mRefCnt = 0;
mScriptObject = nsnull;
}
nsOptionList::nsOptionList(nsIDOMHTMLCollection* aCollection)
{
mRefCnt = 0;
mScriptObject = nsnull;
if (aCollection) {
PRUint32 length = 0;
aCollection->GetLength(&length);
nsIDOMNode* node;
for (PRUint32 elemX = 0; elemX < length; elemX++) {
nsresult result = aCollection->Item(elemX, &node); // this assumes an ADDREF
if ((NS_OK == result) && node) {
nsIDOMHTMLOptionElement* option = nsnull;
result = node->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option);
if ((NS_OK == result) && option) {
mElements.AppendElement(node); // keep the node ref count
NS_RELEASE(option);
}
}
}
}
}
nsOptionList::~nsOptionList()
{
Clear();
}
nsresult nsOptionList::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
if (aIID.Equals(kIDOMHTMLCollectionIID)) {
*aInstancePtr = (void*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kIScriptObjectOwnerIID)) {
*aInstancePtr = (void*)(nsIScriptObjectOwner*)this;
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIDOMHTMLCollection*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMPL_ADDREF(nsOptionList)
NS_IMPL_RELEASE(nsOptionList)
nsresult nsOptionList::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLCollection(aContext, (nsISupports *)(nsIDOMHTMLCollection *)this, nsnull, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
NS_IMETHODIMP
nsOptionList::SetScriptObject(void *aScriptObject)
{
mScriptObject = aScriptObject;
return NS_OK;
}
nsresult nsOptionList::ResetScriptObject()
{
mScriptObject = nsnull;
return NS_OK;
}
// nsIDOMHTMLCollection interface
NS_IMETHODIMP
nsOptionList::GetLength(PRUint32* aLength)
{
*aLength = mElements.Count();
return NS_OK;
}
NS_IMETHODIMP
nsOptionList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
{
*aReturn = (nsIDOMNode*)mElements.ElementAt(aIndex);
NS_ADDREF(*aReturn);
return NS_OK;
}
NS_IMETHODIMP
nsOptionList::NamedItem(const nsString& aName, nsIDOMNode** aReturn)
{
PRUint32 count = mElements.Count();
nsresult result = NS_OK;
*aReturn = nsnull;
for (PRUint32 i = 0; i < count && *aReturn == nsnull; i++) {
nsIDOMHTMLOptionElement *option;
option = (nsIDOMHTMLOptionElement*)mElements.ElementAt(i);
if (nsnull != option) {
nsIContent *content;
result = option->QueryInterface(kIContentIID, (void **)&content);
if (NS_OK == result) {
nsAutoString name;
// XXX Should it be an EqualsIgnoreCase?
if (((content->GetAttribute("NAME", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name))) ||
((content->GetAttribute("ID", name) == NS_CONTENT_ATTR_HAS_VALUE) &&
(aName.Equals(name)))) {
result = option->QueryInterface(kIDOMNodeIID, (void **)aReturn);
}
NS_RELEASE(content);
}
NS_RELEASE(option);
}
}
return result;
}
void
nsOptionList::Clear()
{
PRUint32 numOptions = mElements.Count();
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = (nsIDOMHTMLOptionElement*)mElements.ElementAt(i);
NS_RELEASE(option);
}
mElements.Clear();
}

Просмотреть файл

@ -17,6 +17,9 @@
* Netscape Communications Corporation. All Rights Reserved.
*/
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIScriptObjectOwner.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
@ -26,13 +29,21 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIWidget.h"
#include "nsITextWidget.h"
#include "nsIHTMLAttributes.h"
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFormIID, NS_IFORM_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
class nsHTMLTextAreaElement : public nsIDOMHTMLTextAreaElement,
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent
public nsIScriptObjectOwner,
public nsIDOMEventReceiver,
public nsIHTMLContent,
public nsIFormControl
{
public:
nsHTMLTextAreaElement(nsIAtom* aTag);
@ -85,8 +96,15 @@ public:
// nsIHTMLContent
NS_IMPL_IHTMLCONTENT_USING_GENERIC(mInner)
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD SetWidget(nsIWidget* aWidget);
NS_IMETHOD Init() { return NS_OK; }
protected:
nsGenericHTMLContainerElement mInner;
nsIWidget* mWidget; // XXX this needs to go away when FindFrameWithContent is efficient
nsIForm* mForm;
};
nsresult
@ -107,29 +125,62 @@ nsHTMLTextAreaElement::nsHTMLTextAreaElement(nsIAtom* aTag)
{
NS_INIT_REFCNT();
mInner.Init(this, aTag);
mForm = nsnull;
mWidget = nsnull;
}
nsHTMLTextAreaElement::~nsHTMLTextAreaElement()
{
NS_IF_RELEASE(mWidget);
if (nsnull != mForm) {
// prevent mForm from decrementing its ref count on us
mForm->RemoveElement(this, PR_FALSE);
NS_RELEASE(mForm);
}
}
NS_IMPL_ADDREF(nsHTMLTextAreaElement)
NS_IMPL_RELEASE(nsHTMLTextAreaElement)
NS_IMETHODIMP
nsHTMLTextAreaElement::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return ++mRefCnt;
}
nsresult
nsHTMLTextAreaElement::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_IMPL_HTML_CONTENT_QUERY_INTERFACE(aIID, aInstancePtr, this)
if (aIID.Equals(kIDOMHTMLTextAreaElementIID)) {
nsIDOMHTMLTextAreaElement* tmp = this;
*aInstancePtr = (void*) tmp;
*aInstancePtr = (void*)(nsIDOMHTMLTextAreaElement*) this;
mRefCnt++;
return NS_OK;
}
else if (aIID.Equals(kIFormControlIID)) {
*aInstancePtr = (void*)(nsIFormControl*) this;
mRefCnt++;
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP_(nsrefcnt)
nsHTMLTextAreaElement::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
} else if ((1 == mRefCnt) && mForm) {
mRefCnt = 0;
delete this;
return 0;
} else {
return mRefCnt;
}
}
// nsIDOMHTMLTextAreaElement
nsresult
nsHTMLTextAreaElement::CloneNode(nsIDOMNode** aReturn)
{
@ -144,34 +195,73 @@ nsHTMLTextAreaElement::CloneNode(nsIDOMNode** aReturn)
NS_IMETHODIMP
nsHTMLTextAreaElement::GetForm(nsIDOMHTMLFormElement** aForm)
{
*aForm = nsnull;/* XXX */
*aForm = nsnull;
if (nsnull != mForm) {
nsIDOMHTMLFormElement* formElem = nsnull;
nsresult result = mForm->QueryInterface(kIDOMHTMLFormElementIID, (void**)&formElem);
if (NS_OK == result) {
*aForm = formElem;
}
}
return NS_OK;
}
// 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
nsHTMLTextAreaElement::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_IMETHODIMP
nsHTMLTextAreaElement::Blur() // XXX not tested
{
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Blur()
nsHTMLTextAreaElement::Focus() // XXX not tested
{
// XXX write me
if (nsnull != mWidget) {
mWidget->SetFocus();
}
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Focus()
nsHTMLTextAreaElement::Select() // XXX not tested
{
// XXX write me
return NS_OK;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::Select()
{
// XXX write me
if (nsnull != mWidget) {
nsITextWidget *textWidget;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID, (void**)&textWidget)) {
textWidget->SelectAll();
NS_RELEASE(textWidget);
}
}
return NS_OK;
}
@ -189,7 +279,31 @@ nsHTMLTextAreaElement::StringToAttribute(nsIAtom* aAttribute,
const nsString& aValue,
nsHTMLValue& aResult)
{
// XXX write me
if (aAttribute == nsHTMLAtoms::align) {
if (nsGenericHTMLElement::ParseFormAlignValue(aValue, aResult)) {
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::disabled) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::cols) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::readonly) {
aResult.SetEmptyValue();
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::rows) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
else if (aAttribute == nsHTMLAtoms::tabindex) {
nsGenericHTMLElement::ParseValue(aValue, 0, aResult, eHTMLUnit_Integer);
return NS_CONTENT_ATTR_HAS_VALUE;
}
return NS_CONTENT_ATTR_NOT_THERE;
}
@ -198,7 +312,12 @@ nsHTMLTextAreaElement::AttributeToString(nsIAtom* aAttribute,
nsHTMLValue& aValue,
nsString& aResult) const
{
// XXX write me
if (aAttribute == nsHTMLAtoms::align) {
if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
nsGenericHTMLElement::FormAlignValueToString(aValue, aResult);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
return mInner.AttributeToString(aAttribute, aValue, aResult);
}
@ -207,7 +326,26 @@ MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
// XXX write me
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
@ -229,3 +367,29 @@ nsHTMLTextAreaElement::HandleDOMEvent(nsIPresContext& aPresContext,
return mInner.HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
aFlags, aEventStatus);
}
// nsIFormControl
NS_IMETHODIMP
nsHTMLTextAreaElement::GetType(PRInt32* aType)
{
if (aType) {
*aType = NS_FORM_TEXTAREA;
return NS_OK;
} else {
return NS_FORM_NOTOK;
}
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
}
return NS_OK;
}

Просмотреть файл

@ -36,8 +36,9 @@
#include "nsIDOMText.h"
#include "nsHTMLForms.h"
#include "nsIFormManager.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIFormControl.h"
#include "nsIImageMap.h"
@ -48,6 +49,7 @@
#include "nsIFrame.h"
#include "nsIWebShell.h"
#include "nsIHTMLDocument.h"
// XXX Go through a factory for this one
#include "nsICSSParser.h"
@ -59,11 +61,16 @@ static NS_DEFINE_IID(kIDOMHTMLTitleElementIID, NS_IDOMHTMLTITLEELEMENT_IID);
#define XXX_ART_HACK 1
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
static NS_DEFINE_IID(kIHTMLContentIID, NS_IHTMLCONTENT_IID);
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIHTMLContentSinkIID, NS_IHTML_CONTENT_SINK_IID);
static NS_DEFINE_IID(kIHTTPUrlIID, NS_IHTTPURL_IID);
static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIHTMLDocumentIID, NS_IHTMLDOCUMENT_IID);
//----------------------------------------------------------------------
@ -174,7 +181,7 @@ public:
PRInt32 mInMonolithicContainer;
PRBool mDirty;
PRBool mLayoutStarted;
nsIFormManager* mCurrentForm;
nsIDOMHTMLFormElement* mCurrentForm;
nsIImageMap* mCurrentMap;
SinkContext** mContexts;
@ -236,8 +243,6 @@ public:
nsresult AddText(const nsString& aText);
nsresult FlushText(PRBool* aDidFlush = nsnull);
nsresult AddOptionText(const nsIParserNode& aNode);
void MaybeMarkSinkDirty();
HTMLContentSink* mSink;
@ -260,8 +265,6 @@ public:
PRInt32 mTextLength;
PRInt32 mTextSize;
nsIHTMLContent* mCurrentSelect;
nsIHTMLContent* mCurrentOption;
};
//----------------------------------------------------------------------
@ -449,13 +452,24 @@ AddAttributes(const nsIParserNode& aNode,
return NS_OK;
}
void SetForm(nsIHTMLContent* aContent, nsIDOMHTMLFormElement* aForm)
{
nsIFormControl* formControl = nsnull;
nsresult result = aContent->QueryInterface(kIFormControlIID, (void**)&formControl);
if ((NS_OK == result) && formControl) {
formControl->SetForm(aForm);
NS_RELEASE(formControl);
}
}
// XXX compare switch statement against nsHTMLTags.h's list
static nsresult
MakeContentObject(nsHTMLTag aNodeType,
nsIAtom* aAtom,
nsIFormManager* aForm,
nsIDOMHTMLFormElement* aForm,
nsIWebShell* aWebShell,
nsIHTMLContent** aResult)
nsIHTMLContent** aResult,
const nsString* aContent = nsnull)
{
nsresult rv = NS_OK;
switch (aNodeType) {
@ -512,7 +526,11 @@ MakeContentObject(nsHTMLTag aNodeType,
rv = NS_NewHTMLFontElement(aResult, aAtom);
break;
case eHTMLTag_form:
rv = NS_NewHTMLFormElement(aResult, aAtom);
// the form was already created
*aResult = nsnull;
if (aForm) {
rv = aForm->QueryInterface(kIHTMLContentIID, (void**)aResult);
}
break;
case eHTMLTag_frame:
rv = NS_NewHTMLFrameElement(aResult, aAtom);
@ -542,6 +560,7 @@ MakeContentObject(nsHTMLTag aNodeType,
break;
case eHTMLTag_input:
rv = NS_NewHTMLInputElement(aResult, aAtom);
SetForm(*aResult, aForm);
break;
case eHTMLTag_isindex:
rv = NS_NewHTMLIsIndexElement(aResult, aAtom);
@ -577,7 +596,7 @@ MakeContentObject(nsHTMLTag aNodeType,
rv = NS_NewHTMLOptGroupElement(aResult, aAtom);
break;
case eHTMLTag_option:
rv = NS_NewHTMLOption(aResult, aAtom);/* XXX old style */
rv = NS_NewHTMLOptionElement(aResult, aAtom);
break;
case eHTMLTag_p:
rv = NS_NewHTMLParagraphElement(aResult, aAtom);
@ -595,7 +614,8 @@ MakeContentObject(nsHTMLTag aNodeType,
rv = NS_NewHTMLScriptElement(aResult, aAtom);
break;
case eHTMLTag_select:
rv = NS_NewHTMLSelect(aResult, aAtom, aForm);/* XXX old style */
rv = NS_NewHTMLSelectElement(aResult, aAtom);
SetForm(*aResult, aForm);
break;
case eHTMLTag_spacer:
rv = NS_NewHTMLSpacerElement(aResult, aAtom);
@ -617,6 +637,17 @@ MakeContentObject(nsHTMLTag aNodeType,
break;
case eHTMLTag_textarea:
rv = NS_NewHTMLTextAreaElement(aResult, aAtom);
// XXX why is textarea not a container. If it were, this code would not be necessary
// If the text area has some content, set it
if (aContent && (aContent->Length() > 0)) {
nsIDOMHTMLTextAreaElement* taElem;
rv = (*aResult)->QueryInterface(kIDOMHTMLTextAreaElementIID, (void **)&taElem);
if ((NS_OK == rv) && taElem) {
taElem->SetDefaultValue(*aContent);
NS_RELEASE(taElem);
}
}
SetForm(*aResult, aForm);
break;
case eHTMLTag_title:
rv = NS_NewHTMLTitleElement(aResult, aAtom);
@ -634,13 +665,44 @@ MakeContentObject(nsHTMLTag aNodeType,
return rv;
}
#if 0
// XXX is this logic needed by nsDOMHTMLOptionElement?
void
GetOptionText(const nsIParserNode& aNode, nsString& aText)
{
aText.SetLength(0);
switch (aNode.GetTokenType()) {
case eToken_text:
case eToken_whitespace:
case eToken_newline:
aText.Append(aNode.GetText());
break;
case eToken_entity:
{
nsAutoString tmp2("");
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp2);
if (unicode < 0) {
aText.Append(aNode.GetText());
} else {
aText.Append(tmp2);
}
}
break;
}
nsAutoString x;
char* y = aText.ToNewCString();
printf("foo");
}
#endif
/**
* Factory subroutine to create all of the html content objects.
*/
static nsresult
CreateContentObject(const nsIParserNode& aNode,
nsHTMLTag aNodeType,
nsIFormManager* aForm,
nsIDOMHTMLFormElement* aForm,
nsIWebShell* aWebShell,
nsIHTMLContent** aResult)
{
@ -660,7 +722,7 @@ CreateContentObject(const nsIParserNode& aNode,
// Make the content object
nsresult rv;
// XXX right now this code is here because we need aNode to create
// images, textareas and input form elements. As soon as all of the
// generic content code is in use, it can be moved up into
@ -720,69 +782,16 @@ CreateContentObject(const nsIParserNode& aNode,
rv = NS_NewHTMLImageElement(aResult, atom);
#endif /* XXX */
break;
case eHTMLTag_input:
{
nsAutoString val;
if (FindAttribute(aNode, "type", val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewHTMLInputSubmit(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewHTMLInputReset(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewHTMLInputButton(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewHTMLInputCheckbox(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewHTMLInputFile(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewHTMLInputHidden(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewHTMLInputImage(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewHTMLInputPassword(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewHTMLInputRadio(aResult, atom, aForm);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewHTMLInputText(aResult, atom, aForm);
}
else {
rv = NS_NewHTMLInputText(aResult, atom, aForm);
}
}
else {
rv = NS_NewHTMLInputText(aResult, atom, aForm);
}
}
break;
case eHTMLTag_textarea:
{
const nsString& content = aNode.GetSkippedContent();
rv = NS_NewHTMLTextArea(aResult, atom, aForm);
if (NS_OK == rv) {
// If the text area has some content, give it to it now
if (content.Length() > 0) {
nsIFormControl* ctrl;
rv = (*aResult)->QueryInterface(kIFormControlIID, (void **)&ctrl);
if (NS_OK == rv) {
ctrl->SetContent(content);
NS_RELEASE(ctrl);
}
}
}
}
break;
default:
rv = MakeContentObject(aNodeType, atom, aForm, aWebShell, aResult);
break;
{
// XXX why is textarea not a container?
nsAutoString content;
if (eHTMLTag_textarea == aNodeType) {
content = aNode.GetSkippedContent();
}
rv = MakeContentObject(aNodeType, atom, aForm, aWebShell, aResult, &content);
break;
}
}
NS_RELEASE(atom);
@ -822,8 +831,6 @@ SinkContext::SinkContext(HTMLContentSink* aSink)
mText = nsnull;
mTextLength = 0;
mTextSize = 0;
mCurrentOption = nsnull;
mCurrentSelect = nsnull;
}
SinkContext::~SinkContext()
@ -837,8 +844,6 @@ SinkContext::~SinkContext()
if (nsnull != mText) {
delete [] mText;
}
NS_IF_RELEASE(mCurrentOption);
NS_IF_RELEASE(mCurrentSelect);
}
nsresult
@ -923,16 +928,6 @@ SinkContext::OpenContainer(const nsIParserNode& aNode)
case eHTMLTag_a:
mSink->ProcessATag(aNode, content);
break;
case eHTMLTag_select:
NS_IF_RELEASE(mCurrentSelect);
mCurrentSelect = content;
NS_IF_ADDREF(content);
break;
case eHTMLTag_option:
NS_IF_RELEASE(mCurrentOption);
mCurrentOption = content;
NS_IF_ADDREF(content);
break;
case eHTMLTag_table:
mSink->mInMonolithicContainer++;
break;
@ -964,12 +959,6 @@ SinkContext::CloseContainer(const nsIParserNode& aNode)
// Special handling for certain tags
switch (nodeType) {
case eHTMLTag_option:
NS_IF_RELEASE(mCurrentOption);
break;
case eHTMLTag_select:
NS_IF_RELEASE(mCurrentSelect);
break;
case eHTMLTag_table:
mSink->mInMonolithicContainer--;
break;
@ -989,12 +978,6 @@ SinkContext::AddLeaf(const nsIParserNode& aNode)
nsresult rv = NS_OK;
// XXX temporary hack until option layout code can find content
// the proper way.
if (eHTMLTag_option == mStack[mStackPos-1].mType) {
return AddOptionText(aNode);
}
switch (aNode.GetTokenType()) {
case eToken_start:
{
@ -1181,44 +1164,6 @@ SinkContext::FlushText(PRBool* aDidFlush)
return rv;
}
nsresult
SinkContext::AddOptionText(const nsIParserNode& aNode)
{
if ((nsnull != mCurrentSelect) && (nsnull != mCurrentOption)) {
nsIFormControl* control = nsnull;
mCurrentOption->QueryInterface(kIFormControlIID, (void **)&control);
if (nsnull != control) {
// Get current content and append on the new content
nsAutoString currentText;
control->GetContent(currentText);
switch (aNode.GetTokenType()) {
case eToken_text:
case eToken_whitespace:
case eToken_newline:
currentText.Append(aNode.GetText());
break;
case eToken_entity:
{
nsAutoString tmp2("");
PRInt32 unicode = aNode.TranslateToUnicodeStr(tmp2);
if (unicode < 0) {
currentText.Append(aNode.GetText());
} else {
currentText.Append(tmp2);
}
}
break;
}
control->SetContent(currentText);
NS_RELEASE(control);
}
}
return NS_OK;
}
//----------------------------------------------------------------------
nsresult
NS_NewHTMLContentSink(nsIHTMLContentSink** aResult,
@ -1610,7 +1555,6 @@ HTMLContentSink::CloseBody(const nsIParserNode& aNode)
return NS_OK;
}
// XXX add code to place form into the content model
NS_IMETHODIMP
HTMLContentSink::OpenForm(const nsIParserNode& aNode)
{
@ -1622,44 +1566,28 @@ HTMLContentSink::OpenForm(const nsIParserNode& aNode)
// Close out previous form if it's there
NS_IF_RELEASE(mCurrentForm);
// Create new form
// set the current form
nsAutoString tmp("FORM");
nsIAtom* atom = NS_NewAtom(tmp);
if (nsnull == atom) {
return NS_ERROR_OUT_OF_MEMORY;
nsIHTMLContent* iContent = nsnull;
nsresult rv = NS_NewHTMLFormElement(&iContent, atom);
if ((NS_OK == rv) && iContent) {
iContent->QueryInterface(kIDOMHTMLFormElementIID, (void**)&mCurrentForm);
NS_RELEASE(iContent);
}
nsresult rv = NS_NewHTMLForm(&mCurrentForm, atom);
NS_RELEASE(atom);
if (NS_OK == rv) {
// XXX replace with AddAttributes when form's implement nsIHTMLContent
// Add tag attributes to the form; we can't use AddAttributes
// because mCurrentForm is not an nsIHTMLContent (yet).
nsIScriptContextOwner* sco = mDocument->GetScriptContextOwner();
nsAutoString k, v;
PRInt32 ac = aNode.GetAttributeCount();
for (PRInt32 i = 0; i < ac; i++) {
// Get upper-cased key
const nsString& key = aNode.GetKeyAt(i);
k.SetLength(0);
k.Append(key);
k.ToUpperCase();
AddLeaf(aNode);
// Get value and remove mandatory quotes
GetAttributeValueAt(aNode, i, v, sco);
mCurrentForm->SetAttribute(k, v);
}
NS_IF_RELEASE(sco);
// XXX Temporary code till forms become real content
// Add the form to the document
((nsHTMLDocument*)mDocument)->AddForm(mCurrentForm);
nsIContent *content;
if (NS_OK == mCurrentForm->QueryInterface(kIContentIID, (void **)&content)) {
content->SetDocument(mDocument);
NS_RELEASE(content);
}
}
// 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);
// }
//}
return NS_OK;
}

Просмотреть файл

@ -15,6 +15,7 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsHTMLDocument.h"
#include "nsIParser.h"
#include "nsIHTMLContentSink.h"
@ -31,6 +32,7 @@
#include "nsIDOMNode.h" // for Find
#include "nsIDOMElement.h"
#include "nsIDOMText.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIPostToServer.h"
#include "nsIStreamListener.h"
#include "nsIURL.h"
@ -88,7 +90,6 @@ nsHTMLDocument::nsHTMLDocument()
mEmbeds = nsnull;
mLinks = nsnull;
mAnchors = nsnull;
mForms = nsnull;
mNamedItems = nsnull;
mParser = nsnull;
nsHTMLAtoms::AddrefAtoms();
@ -108,27 +109,21 @@ nsHTMLDocument::nsHTMLDocument()
mParentStack = (nsIDOMNode**) new PRUint32[32];
mChildStack = (nsIDOMNode**) new PRUint32[32];
mBodyContent = nsnull;
mForms = nsnull;
}
nsHTMLDocument::~nsHTMLDocument()
{
// XXX Temporary code till forms become real content
PRInt32 i;
for (i = 0; i < mTempForms.Count(); i++) {
nsIFormManager *form = (nsIFormManager *)mTempForms.ElementAt(i);
if (nsnull != form) {
NS_RELEASE(form);
}
}
DeleteNamedItems();
NS_IF_RELEASE(mImages);
NS_IF_RELEASE(mApplets);
NS_IF_RELEASE(mEmbeds);
NS_IF_RELEASE(mLinks);
NS_IF_RELEASE(mAnchors);
NS_IF_RELEASE(mForms);
NS_IF_RELEASE(mAttrStyleSheet);
NS_IF_RELEASE(mAttrStyleSheet);
NS_IF_RELEASE(mStyleAttrStyleSheet);
NS_IF_RELEASE(mParser);
for (i = 0; i < mImageMaps.Count(); i++) {
@ -136,6 +131,10 @@ nsHTMLDocument::~nsHTMLDocument()
NS_RELEASE(map);
}
if (mForms) {
mForms->Reset();
NS_RELEASE(mForms);
}
// XXX don't bother doing this until the dll is unloaded???
// nsHTMLAtoms::ReleaseAtoms();
@ -337,41 +336,6 @@ NS_IMETHODIMP nsHTMLDocument::GetImageMap(const nsString& aMapName,
return 1;/* XXX NS_NOT_FOUND */
}
// XXX Temporary form methods. Forms will soon become actual content
// elements. For now, the document keeps a list of them.
NS_IMETHODIMP
nsHTMLDocument::AddForm(nsIFormManager *aForm)
{
NS_PRECONDITION(nsnull != aForm, "null ptr");
if (nsnull == aForm) {
return NS_ERROR_NULL_POINTER;
}
if (mTempForms.AppendElement(aForm)) {
NS_ADDREF(aForm);
return NS_OK;
}
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP_(PRInt32)
nsHTMLDocument::GetFormCount() const
{
return mTempForms.Count();
}
NS_IMETHODIMP
nsHTMLDocument::GetFormAt(PRInt32 aIndex, nsIFormManager **aForm) const
{
*aForm = (nsIFormManager *)mTempForms.ElementAt(aIndex);
if (nsnull != *aForm) {
NS_ADDREF(*aForm);
return NS_OK;
}
return 1;/* XXX NS_NOT_FOUND */
}
NS_IMETHODIMP nsHTMLDocument::GetAttributeStyleSheet(nsIHTMLStyleSheet** aResult)
{
NS_PRECONDITION(nsnull != aResult, "null ptr");
@ -596,57 +560,6 @@ nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
return NS_OK;
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// XXX Temporary till form becomes real content
class nsTempFormContentList : public nsContentList {
public:
nsTempFormContentList(nsHTMLDocument *aDocument);
~nsTempFormContentList();
};
nsTempFormContentList::nsTempFormContentList(nsHTMLDocument *aDocument) : nsContentList(aDocument)
{
PRInt32 i, count = aDocument->GetFormCount();
for (i=0; i < count; i++) {
nsIFormManager *form;
if (NS_OK == aDocument->GetFormAt(i, &form)) {
nsIContent *content;
if (NS_OK == form->QueryInterface(kIContentIID, (void **)&content)) {
Add(content);
NS_RELEASE(content);
}
NS_RELEASE(form);
}
}
}
nsTempFormContentList::~nsTempFormContentList()
{
mDocument = nsnull;
}
NS_IMETHODIMP
nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
{
if (nsnull == mForms) {
mForms = new nsTempFormContentList(this);
if (nsnull == mForms) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(mForms);
}
*aForms = (nsIDOMHTMLCollection *)mForms;
NS_ADDREF(mForms);
return NS_OK;
}
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PRBool
nsHTMLDocument::MatchAnchors(nsIContent *aContent)
{
@ -1006,19 +919,6 @@ nsHTMLDocument::NamedItem(const nsString& aName, nsIDOMElement** aReturn)
mNamedItems = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
PL_CompareValues, nsnull, nsnull);
RegisterNamedItems(mRootContent, PR_FALSE);
// XXX Need to do this until forms become real content
PRInt32 i, count = mTempForms.Count();
for (i = 0; i < count; i++) {
nsIFormManager *form = (nsIFormManager *)mTempForms.ElementAt(i);
if (NS_OK == form->QueryInterface(kIContentIID, (void **)&content)) {
nsAutoString value;
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(name, value)) {
char *nameStr = value.ToNewCString();
PL_HashTableAdd(mNamedItems, nameStr, content);
}
NS_RELEASE(content);
}
}
}
char *str = aName.ToNewCString();
@ -1987,3 +1887,47 @@ NS_IMETHODIMP nsHTMLDocument::FindNext(const nsString &aSearchStr, PRBool aMatch
return NS_OK;
}
// forms related stuff
// XXX remove this if GetForms is sufficient
NS_IMETHODIMP
nsHTMLDocument::AddForm(nsIDOMHTMLFormElement *aForm)
{
NS_PRECONDITION(nsnull != aForm, "null ptr");
if (nsnull == aForm) {
return NS_ERROR_NULL_POINTER;
}
if (!mForms) {
nsIDOMHTMLCollection* forms = nsnull;
GetForms(&forms);
}
nsIContent* iContent = nsnull;
nsresult result = aForm->QueryInterface(kIContentIID, (void**)&iContent);
if ((NS_OK == result) && iContent) {
if (mForms->Add(iContent)) {
NS_RELEASE(iContent);
return NS_OK;
}
}
return result;
}
NS_IMETHODIMP
nsHTMLDocument::GetForms(nsIDOMHTMLCollection** aForms)
{
if (nsnull == mForms) {
nsAutoString tag("form");
mForms = new nsContentList(this, tag);
if (nsnull == mForms) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
*aForms = (nsIDOMHTMLCollection *)mForms;
NS_ADDREF(mForms);
return NS_OK;
}

Просмотреть файл

@ -53,17 +53,6 @@ public:
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult);
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// XXX Temporary form methods. Forms will soon become actual content
// elements. For now, the document keeps a list of them.
NS_IMETHOD AddForm(nsIFormManager *aForm);
NS_IMETHOD_(PRInt32) GetFormCount() const;
NS_IMETHOD GetFormAt(PRInt32 aIndex, nsIFormManager **aForm) const;
// XXX
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aStyleSheet);
NS_IMETHOD GetDTDMode(nsDTDMode& aMode);
@ -100,6 +89,8 @@ public:
// nsIDOMHTMLDocument interface
NS_DECL_IDOMHTMLDOCUMENT
NS_DECL_IDOMNSHTMLDOCUMENT
// the following is not part of nsIDOMHTMLDOCUMENT but allows the content sink to add forms
NS_IMETHOD AddForm(nsIDOMHTMLFormElement* aForm);
// From nsIScriptObjectOwner interface, implemented by nsDocument
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
@ -163,7 +154,6 @@ protected:
nsIHTMLCSSStyleSheet* mStyleAttrStyleSheet;
nsDTDMode mDTDMode;
nsVoidArray mImageMaps;
nsVoidArray mTempForms; // XXX Temporary
nsContentList *mImages;
nsContentList *mApplets;

Просмотреть файл

@ -21,7 +21,8 @@
#include "nsISupports.h"
class nsIImageMap;
class nsString;
class nsIFormManager;
class nsIDOMHTMLCollection;
class nsIDOMHTMLFormElement;
class nsIHTMLStyleSheet;
/* b2a848b0-d0a9-11d1-89b1-006008911b81 */
@ -44,20 +45,13 @@ public:
NS_IMETHOD AddImageMap(nsIImageMap* aMap) = 0;
NS_IMETHOD GetImageMap(const nsString& aMapName, nsIImageMap** aResult) = 0;
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// XXX Temporary form methods. Forms will soon become actual content
// elements. For now, the document keeps a list of them.
NS_IMETHOD AddForm(nsIFormManager *aForm) = 0;
NS_IMETHOD_(PRInt32) GetFormCount() const = 0;
NS_IMETHOD GetFormAt(PRInt32 aIndex, nsIFormManager **aForm) const = 0;
// XXX
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
NS_IMETHOD GetAttributeStyleSheet(nsIHTMLStyleSheet** aStyleSheet) = 0;
NS_IMETHOD AddForm(nsIDOMHTMLFormElement* aForm) = 0;
NS_IMETHOD GetForms(nsIDOMHTMLCollection** aForms) = 0;
/**
* Access DTD compatibility mode for this document
*/

Просмотреть файл

@ -18,7 +18,6 @@
DEPTH=../../../..
EXPORTS = \
nsIFormControl.h \
nsIFormManager.h \
$(NULL)

Просмотреть файл

@ -17,7 +17,7 @@
DEPTH=..\..\..\..
EXPORTS=nsIFormControl.h nsIFormManager.h
EXPORTS=nsIFormManager.h
MODULE=raptor

Просмотреть файл

@ -1,122 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIFormControl_h___
#define nsIFormControl_h___
#include "nsISupports.h"
class nsIFormManager;
#define NS_IFORMCONTROL_IID \
{ 0x282ff440, 0xcd7e, 0x11d1, \
{0x89, 0xad, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
// XXX XPCOM'ize me
/**
* Interface which all form controls (e.g. buttons, checkboxes, text,
* radio buttons, select, etc) implement.
**/
class nsIFormControl : public nsISupports {
public:
virtual void GetType(nsString& aType) const = 0;
virtual PRBool GetChecked(PRBool aGetInitialValue) const = 0;
virtual void SetChecked(PRBool aState, PRBool aSetInitialValue) = 0;
virtual PRBool GetCanSubmit() const = 0;
/**
* Get the form manager which manages this control.
* @return the form manager
*/
virtual nsIFormManager* GetFormManager() const = 0;
/**
* Get the max number of values that this control can have; the actual
* number of values may be less.
* @return the max number of values
*/
virtual PRInt32 GetMaxNumValues() = 0;
/**
* Get the content of this control if applicable
* @param aResult the nsString which will be set to the name (out parm)
* @return PR_TRUE if there was content, PR_FALSE otherwise
*/
virtual PRBool GetContent(nsString& aResult) const = 0;
/**
* Get the name of this control. Controls without names will not have any
* data submitted.
* @param aResult the nsString which will be set to the name (out parm).
* If the result has a length of 0, the control has no name
* @return NS_OK if successful
*/
virtual nsresult GetName(nsString& aResult) = 0;
/**
* Get the number of references to this control by other objects.
* @return the ref count
*/
virtual nsrefcnt GetRefCount() const = 0;
/**
* Get the vaules which this control could submit.
* @param aMaxNumValues the maximum number of values to set (in parm)
* @param aNumValues the actual number of values set (out parm)
* @param aValues an array of nsString which contains the values (out parm
* that is allocated by the caller)
* @param aNames an array of nsString which contains the names (out parm
* that is allocated by the caller)
* @return PR_TRUE if any values were set, PR_FALSE otherwise
*/
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames) = 0;
/**
* Return true if this control should have its data submitted
* @param aSubmitter the submit button or text field that caused the submit
*/
virtual PRBool IsSuccessful(nsIFormControl* aSubmitter) const = 0;
/**
* Set this control back to its initial value
*/
virtual void Reset() = 0;
/**
* Set this control to be able to cause a form submission if aFlag is true.
*/
virtual void SetCanSubmit(PRBool aFlag) = 0;
/**
* Set this content of this control. This is a no-op for controls that do not
* have content set explicitly.
*/
virtual void SetContent(const nsString& aValue) = 0;
/**
* Set the form manager for this control
* @param aFormMan the new form manager
* @param aDecrementRef if PR_TRUE, decrement the ref count to the existing
* form manager. This facilitates handling circular references.
*/
virtual void SetFormManager(nsIFormManager* aFormMan, PRBool aDecrementRef = PR_TRUE) = 0;
};
#endif /* nsIFormControl_h___ */

Просмотреть файл

@ -19,54 +19,25 @@
#define nsIFormManager_h___
#include "nsISupports.h"
#include "nsIContent.h"
class nsIFormControl;
class nsIPresContext;
class nsIFrame;
class nsString;
// IID for the nsIFormManager interface
#define NS_IFORMMANAGER_IID \
{ 0x592daa01, 0xcb23, 0x11d1, \
{ 0x80, 0x2d, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
// this is temporary until a more global solution is developed
enum nsFormRenderingMode {
kBackwardMode = 0, // nav 4
kForwardMode // newest
};
// XXX XPCOM'ize me
/**
* Abstract form manager interface. Form managers are responsible for
* the management of form controls. This includes gathering of data
* for form submission, resetting form controls to their initial state,
* and other programmatic control during form processing.
* Interface to provide submitting and resetting forms
**/
class nsIFormManager : public nsISupports {
public:
// Event methods
/**
* Respond to a radio button being checked. This form manager is responsible
* for radio group coordination.
* @param aRadio the radio button that was checked
*/
virtual void OnRadioChecked(nsIFormControl& aRadio) = 0;
/**
* Reset the values of all of this manager's controls back to their
* initial values. This is in response to a reset button being pushed.
*/
virtual void OnReset() = 0;
/**
* If there is a single text form control, this is identical to OnReset,
* otherwise do nothing. This in response to a carriage return being
* entered within a text control.
*/
virtual void OnReturn() = 0;
NS_IMETHOD OnReset() = 0;
/**
* Submit the values of this manager's controls depending on its action,
@ -75,75 +46,8 @@ public:
* @param aFrame the frame of the submit button
* @param aSubmitter the control that caused the submit
*/
virtual void OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame,
nsIFormControl* aSubmitter) = 0;
NS_IMETHOD OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame) = 0;
/**
* This is tbd and is in repsonse to a tab key being entered in one
* of the controls.
*/
virtual void OnTab() = 0;
// methods accessing controls
/**
* Add a control to end of this manager's list of controls
* @param aFormControl the control to add
* @return PR_TRUE if the control was successfully added
*/
virtual PRBool AddFormControl(nsIFormControl* aFormControl) = 0;
/**
* Get the number of controls that this manager has in its list
* @return the number of controls
*/
virtual PRInt32 GetFormControlCount() const = 0;
/**
* Get the control at a specific position in this manager's list
* @param aIndex the position at which to get
* @return the control at that position
*/
virtual nsIFormControl* GetFormControlAt(PRInt32 aIndex) const = 0;
/**
* Remove a control from this manager's list
* @param aFormControl thc control to remove
* @param aChildIsRef if PR_TRUE, the controls ref count will be decremented
* otherwise not. This is to facilitate circular references.
* @return PR_TRUE if the control was successfully removed.
*/
virtual PRBool RemoveFormControl(nsIFormControl* aFormControl,
PRBool aChildIsRef = PR_TRUE) = 0;
// methods accessing attributes
NS_IMETHOD GetAttribute(const nsString& aName, nsString& aResult) const = 0;
/**
* Set the named attribute of this manager
* @param aName the name of the attribute
* @param aValue the value of the attribute
*/
NS_IMETHOD SetAttribute(const nsString& aName, const nsString& aValue) = 0;
// misc methods
/**
* Initialize this form manager after all of the controls have been added
* This makes it possible to determine what the radio groups are.
* @param aReinit if PR_TRUE initialize even if Init has been called before.
*/
virtual void Init(PRBool aReinit) = 0;
/**
* Get the number of references to this form manager by other objects.
* @return the ref count
*/
virtual nsrefcnt GetRefCount() const = 0;
virtual nsFormRenderingMode GetMode() const = 0;
virtual void SetMode(nsFormRenderingMode aMode) = 0;
};
#endif /* nsIFormManager_h___ */

Просмотреть файл

@ -25,15 +25,14 @@ DEFINES += -D_IMPL_NS_HTML
# Note the sophisticated alphabetical ordering :-|
CPPSRCS = \
nsForm.cpp \
nsInput.cpp \
nsInputButton.cpp \
nsInputCheckbox.cpp \
nsInputFile.cpp \
nsInputFrame.cpp \
nsInputRadio.cpp \
nsInputText.cpp \
nsSelect.cpp \
nsFormFrame.cpp \
nsFormControlFrame.cpp \
nsButtonControlFrame.cpp \
nsCheckboxControlFrame.cpp \
nsFileControlFrame.cpp \
nsRadioControlFrame.cpp \
nsTextControlFrame.cpp \
nsSelectControlFrame.cpp \
$(NULL)
MODULE = raptor

Просмотреть файл

@ -23,15 +23,13 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
MODULE=raptor
REQUIRES=xpcom raptor js
CPPSRCS=nsForm.cpp nsInput.cpp nsInputButton.cpp nsInputCheckbox.cpp \
nsInputFile.cpp nsInputFrame.cpp \
nsInputRadio.cpp nsInputText.cpp nsSelect.cpp
CPPSRCS=nsFormFrame.cpp nsFormControlFrame.cpp nsButtonControlFrame.cpp nsCheckboxControlFrame.cpp \
nsFileControlFrame.cpp nsRadioControlFrame.cpp nsTextControlFrame.cpp nsSelectControlFrame.cpp
CPP_OBJS=.\$(OBJDIR)\nsForm.obj .\$(OBJDIR)\nsInput.obj \
.\$(OBJDIR)\nsInputButton.obj .\$(OBJDIR)\nsInputCheckbox.obj \
.\$(OBJDIR)\nsInputFile.obj .\$(OBJDIR)\nsInputFrame.obj \
.\$(OBJDIR)\nsInputRadio.obj \
.\$(OBJDIR)\nsInputText.obj .\$(OBJDIR)\nsSelect.obj
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
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \
-I$(PUBLIC)\dom -I$(PUBLIC)\netlib \

Просмотреть файл

@ -0,0 +1,418 @@
/* -*- 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 "nsFileControlFrame.h"
#include "nsButtonControlFrame.h"
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsIRenderingContext.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIStyleContext.h"
#include "nsLeafFrame.h"
#include "nsCSSRendering.h"
#include "nsHTMLIIDs.h"
#include "nsIButton.h"
#include "nsIViewManager.h"
#include "nsISupports.h"
#include "nsHTMLAtoms.h"
#include "nsIButton.h"
#include "nsIView.h"
#include "nsViewsCID.h"
#include "nsWidgetsCID.h"
#include "nsIDeviceContext.h"
#include "nsIFontCache.h"
#include "nsIFontMetrics.h"
#include "nsIFormControl.h"
#include "nsIImage.h"
#include "nsHTMLImage.h"
#include "nsStyleUtil.h"
#include "nsDOMEvent.h"
#include "nsStyleConsts.h"
#include "nsIHTMLAttributes.h"
#include "nsGenericHTMLElement.h"
#include "nsFormFrame.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
void
nsButtonControlFrame::GetDefaultLabel(nsString& aString)
{
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_RESET == type) {
aString = "Reset";
}
else if (NS_FORM_INPUT_SUBMIT == type) {
aString = "Submit Query";
}
else if (NS_FORM_BROWSE == type) {
aString = "Browse...";
}
else {
aString = " ";
}
}
PRInt32
nsButtonControlFrame::GetMaxNumValues()
{
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) {
return 1;
} else if (NS_FORM_INPUT_IMAGE == type) {
return 2;
} else {
return 0;
}
}
PRBool
nsButtonControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
return PR_FALSE;
}
PRInt32 type;
GetType(&type);
nsAutoString value;
nsresult valResult = GetValue(&value);
if ((NS_FORM_INPUT_IMAGE == type) || (NS_FORM_INPUT_BUTTON == type)) {
char buf[20];
aNumValues = 2;
aValues[0].SetLength(0);
sprintf(&buf[0], "%d", mLastClickPoint.x);
aValues[0].Append(&buf[0]);
aNames[0] = name;
aNames[0].Append(".x");
aValues[1].SetLength(0);
sprintf(&buf[0], "%d", mLastClickPoint.y);
aValues[1].Append(&buf[0]);
aNames[1] = name;
aNames[1].Append(".y");
return PR_TRUE;
}
else if (((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_HIDDEN == type)) &&
(NS_CONTENT_ATTR_HAS_VALUE == valResult)) {
aValues[0] = value;
aNames[0] = name;
aNumValues = 1;
return PR_TRUE;
} else {
aNumValues = 0;
return PR_FALSE;
}
}
nsresult
NS_NewButtonControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsButtonControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsButtonControlFrame::nsButtonControlFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsFormControlFrame(aContent, aParentFrame)
{
}
nsButtonControlFrame::~nsButtonControlFrame()
{
}
nscoord
nsButtonControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(4, aPixToTwip);
}
nscoord
nsButtonControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
nscoord
nsButtonControlFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
//return NSIntPixelsToTwips(4, aPixToTwip);
#ifdef XP_PC
return (nscoord)NSToIntRound((float)aInnerHeight * 0.25f);
#endif
#ifdef XP_UNIX
return (nscoord)NSToIntRound((float)aInnerHeight * 0.50f);
#endif
}
nscoord
nsButtonControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
nsCompatibility mode;
aPresContext.GetCompatibilityMode(mode);
#ifdef XP_PC
if (eCompatibility_NavQuirks == mode) {
return (nscoord)NSToIntRound(float(aInnerWidth) * 0.25f);
} else {
return NSIntPixelsToTwips(10, aPixToTwip) + 8;
}
#endif
#ifdef XP_UNIX
if (eCompatibility_NavQuirks == mode) {
return (nscoord)NSToIntRound(float(aInnerWidth) * 0.5f);
} else {
return NSIntPixelsToTwips(20, aPixToTwip);
}
#endif
}
NS_METHOD
nsButtonControlFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
PRInt32 type;
GetType(&type);
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mVisible) {
// let super do processing if there is no image
if (NS_FORM_INPUT_IMAGE != type) {
return nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
}
// First paint background and borders
nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect);
nsIImage* image = mImageLoader.GetImage();
if (nsnull == image) {
// No image yet
return NS_OK;
}
// Now render the image into our inner area (the area without the
nsRect inner;
GetInnerArea(&aPresContext, inner);
aRenderingContext.DrawImage(image, inner);
}
return NS_OK;
}
void
nsButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
PRInt32 type;
GetType(&type);
if (nsnull != mFormFrame) {
if (NS_FORM_INPUT_RESET == type) {
//Send DOM event
nsEventStatus mStatus;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_RESET;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mFormFrame->OnReset();
}
else if ((NS_FORM_INPUT_SUBMIT == type) || (NS_FORM_INPUT_IMAGE == type)) {
//Send DOM event
nsEventStatus mStatus;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mFormFrame->OnSubmit(aPresContext, this);
}
} else if ((NS_FORM_BROWSE == type) && mFileControlFrame) {
mFileControlFrame->MouseClicked(aPresContext);
}
}
NS_METHOD
nsButtonControlFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_IMAGE == type) {
nsSize ignore;
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore);
AddBordersAndPadding(&aPresContext, aDesiredSize);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
else {
return nsFormControlFrame:: Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
}
void
nsButtonControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_HIDDEN == type) { // there is no physical rep
aDesiredLayoutSize.width = 0;
aDesiredLayoutSize.height = 0;
aDesiredLayoutSize.ascent = 0;
aDesiredLayoutSize.descent = 0;
} else {
if (NS_FORM_INPUT_IMAGE == type) { // there is an image
// Setup url before starting the image load
nsAutoString src;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("SRC", src)) {
mImageLoader.SetURL(src);
}
mImageLoader.GetDesiredSize(aPresContext, aReflowState, aDesiredLayoutSize);
} else { // there is a widget
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
// a browse button shares is style context with its parent nsInputFile
// it uses everything from it except width
if (NS_FORM_BROWSE == type) {
styleSize.width = CSS_NOTSET;
}
nsSize size;
PRBool widthExplicit, heightExplicit;
PRInt32 ignore;
nsAutoString defaultLabel;
GetDefaultLabel(defaultLabel);
nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value,
&defaultLabel, 1, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, spec, size,
widthExplicit, heightExplicit, ignore);
aDesiredLayoutSize.width = size.width;
aDesiredLayoutSize.height= size.height;
}
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
}
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height= aDesiredLayoutSize.height;
}
void
nsButtonControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
{
PRInt32 type;
GetType(&type);
nsIButton* button = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(kIButtonIID,(void**)&button))) {
if (NS_FORM_BROWSE != type) { // browse button always uses default
const nsStyleFont* styleFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
if ((styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT) ||
(styleFont->mFlags & NS_STYLE_FONT_SIZE_EXPLICIT)) {
nsFont widgetFont(styleFont->mFixedFont);
widgetFont.weight = NS_FONT_WEIGHT_NORMAL; // always normal weight
widgetFont.size = styleFont->mFont.size; // normal font size
if (0 == (styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT)) {
widgetFont.name = "Arial"; // XXX windows specific font
}
mWidget->SetFont(widgetFont);
}
else {
// use arial, scaled down one HTML size
// italics, decoration & variant(?) get used
nsFont widgetFont(styleFont->mFont);
widgetFont.name = "Arial"; // XXX windows specific font
widgetFont.weight = NS_FONT_WEIGHT_NORMAL;
const nsFont& normal = aPresContext->GetDefaultFont();
PRInt32 scaler = aPresContext->GetFontScaler();
float scaleFactor = nsStyleUtil::GetScalingFactor(scaler);
PRInt32 fontIndex = nsStyleUtil::FindNextSmallerFontSize(widgetFont.size, (PRInt32)normal.size, scaleFactor);
widgetFont.size = nsStyleUtil::CalcFontPointSize(fontIndex, (PRInt32)normal.size, scaleFactor);
mWidget->SetFont(widgetFont);
}
}
}
else {
NS_ASSERTION(0, "no widget in button control");
}
nsString value;
nsresult result = GetValue(&value);
if (button != nsnull) {
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
button->SetLabel(value);
} else {
nsAutoString label;
GetDefaultLabel(label);
button->SetLabel(label);
}
}
NS_IF_RELEASE(button);
}
const nsIID&
nsButtonControlFrame::GetIID()
{
static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
return kButtonIID;
}
const nsIID&
nsButtonControlFrame::GetCID()
{
static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
return kButtonCID;
}

Просмотреть файл

@ -0,0 +1,77 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsButtonControlFrame_h___
#define nsButtonControlFrame_h___
#include "nsFormControlFrame.h"
#include "nsHTMLImage.h"
class nsFileControlFrame;
class nsButtonControlFrame : public nsFormControlFrame {
public:
nsButtonControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
nsFileControlFrame* GetFileControlFrame() { return mFileControlFrame; }
void SetFileControlFrame(nsFileControlFrame* aFrame) { mFileControlFrame = aFrame; }
void GetDefaultLabel(nsString& aLabel);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
protected:
virtual ~nsButtonControlFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
nsHTMLImageLoader mImageLoader;
nsFileControlFrame* mFileControlFrame; // for browse buttons only
};
#endif

Просмотреть файл

@ -0,0 +1,238 @@
/* -*- 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 "nsICheckButton.h"
#include "nsFormControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsWidgetsCID.h"
#include "nsIView.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsStyleUtil.h"
#include "nsIFormControl.h"
static NS_DEFINE_IID(kICheckButtonIID, NS_ICHECKBUTTON_IID);
//static NS_DEFINE_IID(kIHTMLContentIID, NS_IHTMLCONTENT_IID);
class nsCheckboxControlFrame : public nsFormControlFrame {
public:
nsCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
NS_IMETHOD GetChecked(PRBool* aResult);
protected:
virtual ~nsCheckboxControlFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewCheckboxControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsCheckboxControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsCheckboxControlFrame::nsCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsFormControlFrame(aContent, aParentFrame)
{
}
nsCheckboxControlFrame::~nsCheckboxControlFrame()
{
}
const nsIID&
nsCheckboxControlFrame::GetIID()
{
static NS_DEFINE_IID(kCheckboxIID, NS_ICHECKBUTTON_IID);
return kCheckboxIID;
}
const nsIID&
nsCheckboxControlFrame::GetCID()
{
static NS_DEFINE_IID(kCheckboxCID, NS_CHECKBUTTON_CID);
return kCheckboxCID;
}
void
nsCheckboxControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
float p2t = aPresContext->GetPixelsToTwips();
#ifdef XP_PC
aDesiredWidgetSize.width = NSIntPixelsToTwips(12, p2t);
aDesiredWidgetSize.height = NSIntPixelsToTwips(12, p2t);
#endif
#ifdef XP_PC
aDesiredWidgetSize.width = NSIntPixelsToTwips(20, p2t);
aDesiredWidgetSize.height = NSIntPixelsToTwips(20, p2t);
#endif
aDesiredLayoutSize.width = aDesiredWidgetSize.width;
aDesiredLayoutSize.height = aDesiredWidgetSize.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
}
NS_IMETHODIMP
nsCheckboxControlFrame::GetChecked(PRBool* aResult)
{
nsresult result = NS_FORM_NOTOK;
*aResult = PR_FALSE;
if (mContent) {
nsIHTMLContent* iContent = nsnull;
result = mContent->QueryInterface(kIHTMLContentIID, (void**)&iContent);
if ((NS_OK == result) && iContent) {
nsHTMLValue value;
result = iContent->GetAttribute(nsHTMLAtoms::checked, value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
*aResult = PR_TRUE;
}
NS_RELEASE(iContent);
}
}
return result;
}
void
nsCheckboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
{
PRBool checked;
nsresult result = GetChecked(&checked);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
// set the widget to the initial state
nsICheckButton* checkbox = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(GetIID(),(void**)&checkbox))) {
checkbox->SetState(checked);
const nsStyleColor* color =
nsStyleUtil::FindNonTransparentBackground(mStyleContext);
if (nsnull != color) {
mWidget->SetBackgroundColor(color->mBackgroundColor);
} else {
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
}
NS_IF_RELEASE(checkbox);
}
}
}
void
nsCheckboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
nsICheckButton* checkbox = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(GetIID(),(void**)&checkbox))) {
PRBool oldState;
checkbox->GetState(oldState);
PRBool newState = oldState ? PR_FALSE : PR_TRUE;
checkbox->SetState(newState);
NS_IF_RELEASE(checkbox);
}
}
PRInt32
nsCheckboxControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsCheckboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult nameResult = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != nameResult)) {
return PR_FALSE;
}
PRBool result = PR_TRUE;
nsAutoString value;
nsresult valueResult = GetValue(&value);
nsICheckButton* checkBox = nsnull;
if ((nsnull != mWidget) &&
(NS_OK == mWidget->QueryInterface(kICheckButtonIID,(void**)&checkBox))) {
PRBool state = PR_FALSE;
checkBox->GetState(state);
if (PR_TRUE != state) {
result = PR_FALSE;
} else {
if (NS_CONTENT_ATTR_HAS_VALUE == valueResult) {
aValues[0] = "on";
} else {
aValues[0] = value;
}
aNames[0] = name;
aNumValues = 1;
}
NS_RELEASE(checkBox);
}
return result;
}
void
nsCheckboxControlFrame::Reset()
{
nsICheckButton* checkBox = nsnull;
if ((mWidget != nsnull) &&
(NS_OK == mWidget->QueryInterface(kICheckButtonIID,(void**)&checkBox))) {
PRBool checked;
GetChecked(&checked);
checkBox->SetState(checked);
NS_RELEASE(checkBox);
}
}

Просмотреть файл

@ -0,0 +1,314 @@
/* -*- 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 "nsFileControlFrame.h"
#include "nsButtonControlFrame.h"
#include "nsTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
#include "nsIFileWidget.h"
#include "nsITextWidget.h"
#include "nsWidgetsCID.h"
#include "nsRepository.h"
#include "nsIView.h"
#include "nsHTMLParts.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsHTMLParts.h"
#include "nsIFormControl.h"
// XXX make this pixels
#define CONTROL_SPACING 40
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
nsresult
NS_NewFileControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsFileControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsFileControlFrame::nsFileControlFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsHTMLContainerFrame(aContent, aParentFrame)
{
mTextFrame = nsnull;
mBrowseFrame = nsnull;
mFormFrame = nsnull;
}
nsFileControlFrame::~nsFileControlFrame()
{
}
nsresult
nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
NS_PRECONDITION(0 != aInstancePtr, "null ptr");
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIFormControlFrameIID)) {
*aInstancePtr = (void*) ((nsIFormControlFrame*) this);
return NS_OK;
}
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
PRBool
nsFileControlFrame::IsSuccessful()
{
nsAutoString name;
return (NS_CONTENT_ATTR_HAS_VALUE == GetName(&name));
}
void
nsFileControlFrame::Reset()
{
if (mTextFrame) {
mTextFrame->Reset();
}
}
NS_IMETHODIMP
nsFileControlFrame::GetType(PRInt32* aType) const
{
*aType = NS_FORM_INPUT_FILE;
return NS_OK;
}
// XXX this should be removed when nsView exposes it
nsIWidget*
GetWindowTemp(nsIView *aView)
{
nsIWidget *window = nsnull;
nsIView *ancestor = aView;
while (nsnull != ancestor) {
ancestor->GetWidget(window);
if (nsnull != window) {
return window;
}
ancestor->GetParent(ancestor);
}
return nsnull;
}
// 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)
{
nsIView* textView;
mTextFrame->GetView(textView);
if (nsnull == textView) {
return;
}
nsIWidget* widget;
mTextFrame->GetWidget(&widget);
if (!widget) {
return;
}
nsITextWidget* textWidget;
nsresult result = widget->QueryInterface(kITextWidgetIID, (void**)&textWidget);
if (NS_OK != result) {
NS_RELEASE(widget);
return;
}
nsIView* parentView;
textView->GetParent(parentView);
nsIWidget* parentWidget = GetWindowTemp(parentView);
nsIFileWidget *fileWidget;
nsString title("FileWidget Title <here> mode = save");
nsRepository::CreateInstance(kCFileWidgetCID, nsnull, kIFileWidgetIID, (void**)&fileWidget);
nsString titles[] = {"all files"};
nsString filters[] = {"*.*"};
fileWidget->SetFilterList(1, titles, filters);
fileWidget->Create(parentWidget, title, eMode_load, nsnull, nsnull);
result = fileWidget->Show();
if (result) {
PRUint32 size;
nsString fileName;
fileWidget->GetFile(fileName);
textWidget->SetText(fileName,size);
}
NS_RELEASE(fileWidget);
NS_RELEASE(parentWidget);
NS_RELEASE(textWidget);
NS_RELEASE(widget);
}
void SetType(nsIHTMLContent* aElement, nsString& aValue)
{
nsIHTMLContent* iContent = nsnull;
nsresult result = aElement->QueryInterface(kIHTMLContentIID, (void**)&iContent);
if ((NS_OK == result) && iContent) {
iContent->SetAttribute("type", aValue, PR_FALSE);
NS_RELEASE(iContent);
}
}
NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
PRInt32 numChildren = LengthOf(mFirstChild);
nsIFrame* childFrame;
if (0 == numChildren) {
// XXX This code should move to Init(), someday when the frame construction
// changes are all done and Init() is always getting called...
nsIHTMLContent* text = nsnull;
nsIAtom* tag = NS_NewAtom("text");
NS_NewHTMLInputElement(&text, tag);
text->SetAttribute("type", "text", PR_FALSE);
NS_NewTextControlFrame(text, this, childFrame);
childFrame->SetStyleContext(&aPresContext, mStyleContext);
mTextFrame = (nsTextControlFrame*)childFrame;
mFirstChild = childFrame;
nsIHTMLContent* browse = nsnull;
tag = NS_NewAtom("browse");
NS_NewHTMLInputElement(&browse, tag);
browse->SetAttribute("type", "browse", PR_FALSE);
NS_NewButtonControlFrame(browse, this, childFrame);
((nsButtonControlFrame*)childFrame)->SetFileControlFrame(this);
mBrowseFrame = (nsButtonControlFrame*)childFrame;
childFrame->SetStyleContext(&aPresContext, mStyleContext);
mFirstChild->SetNextSibling(childFrame);
mChildCount = 2;
NS_RELEASE(text);
NS_RELEASE(browse);
}
nsSize maxSize = aReflowState.maxSize;
nsReflowMetrics desiredSize = aDesiredSize;
aDesiredSize.width = CONTROL_SPACING;
aDesiredSize.height = 0;
childFrame = mFirstChild;
nsPoint offset(0,0);
while (nsnull != childFrame) { // reflow, place, size the children
nsReflowState reflowState(childFrame, aReflowState, maxSize);
childFrame->WillReflow(aPresContext);
nsresult result = childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
nsRect rect(offset.x, offset.y, desiredSize.width, desiredSize.height);
childFrame->SetRect(rect);
maxSize.width -= desiredSize.width;
aDesiredSize.width += desiredSize.width;
aDesiredSize.height = desiredSize.height;
childFrame->GetNextSibling(childFrame);
offset.x += desiredSize.width + CONTROL_SPACING;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
PRIntn
nsFileControlFrame::GetSkipSides() const
{
return 0;
}
NS_IMETHODIMP
nsFileControlFrame::GetName(nsString* aResult)
{
nsresult result = NS_FORM_NOTOK;
if (mContent) {
nsIHTMLContent* formControl = nsnull;
result = mContent->QueryInterface(kIHTMLContentIID, (void**)&formControl);
if ((NS_OK == result) && formControl) {
nsHTMLValue value;
result = formControl->GetAttribute(nsHTMLAtoms::name, value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
if (eHTMLUnit_String == value.GetUnit()) {
value.GetStringValue(*aResult);
}
}
NS_RELEASE(formControl);
}
}
return result;
}
PRInt32
nsFileControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsFileControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
return PR_FALSE;
}
// use our name and the text widgets value
aNames[0] = name;
nsresult status = PR_FALSE;
nsIWidget* widget;
nsITextWidget* textWidget;
mTextFrame->GetWidget(&widget);
if (widget && (NS_OK == widget->QueryInterface(kITextWidgetIID, (void**)&textWidget))) {
PRUint32 actualSize;
textWidget->GetText(aValues[0], 0, actualSize);
aNumValues = 1;
NS_RELEASE(textWidget);
status = PR_TRUE;
}
NS_IF_RELEASE(widget);
return status;
}

Просмотреть файл

@ -0,0 +1,255 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsFormControlFrame_h___
#define nsFormControlFrame_h___
#include "nsIFormControlFrame.h"
#include "nsIFormManager.h"
#include "nsHTMLContainer.h"
#include "nsISupports.h"
#include "nsIWidget.h"
#include "nsLeafFrame.h"
#include "nsCoord.h"
class nsIView;
class nsIPresContext;
class nsStyleCoord;
class nsFormFrame;
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
/**
* Enumeration of possible mouse states used to detect mouse clicks
*/
enum nsMouseState {
eMouseNone,
eMouseEnter,
eMouseDown,
eMouseUp
};
struct nsInputDimensionSpec
{
nsIAtom* mColSizeAttr; // attribute used to determine width
PRBool mColSizeAttrInPixels; // is attribute value in pixels (otherwise num chars)
nsIAtom* mColValueAttr; // attribute used to get value to determine size
// if not determined above
nsString* mColDefaultValue; // default value if not determined above
nscoord mColDefaultSize; // default width if not determined above
PRBool mColDefaultSizeInPixels; // is default width in pixels (otherswise num chars)
nsIAtom* mRowSizeAttr; // attribute used to determine height
nscoord mRowDefaultSize; // default height if not determined above
nsInputDimensionSpec(nsIAtom* aColSizeAttr, PRBool aColSizeAttrInPixels,
nsIAtom* aColValueAttr, nsString* aColDefaultValue,
nscoord aColDefaultSize, PRBool aColDefaultSizeInPixels,
nsIAtom* aRowSizeAttr, nscoord aRowDefaultSize)
: mColSizeAttr(aColSizeAttr), mColSizeAttrInPixels(aColSizeAttrInPixels),
mColValueAttr(aColValueAttr),
mColDefaultValue(aColDefaultValue), mColDefaultSize(aColDefaultSize),
mColDefaultSizeInPixels(aColDefaultSizeInPixels),
mRowSizeAttr(aRowSizeAttr), mRowDefaultSize(aRowDefaultSize)
{
}
};
/**
* nsFormControlFrame is the base class for frames of form controls. It
* provides a uniform way of creating widgets, resizing, and painting.
* @see nsLeafFrame and its base classes for more info
*/
class nsFormControlFrame : public nsLeafFrame,
public nsIFormControlFrame
{
public:
/**
* Main constructor
* @param aContent the content representing this frame
* @param aParentFrame the parent frame
*/
nsFormControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
static nscoord CalculateSize (nsIPresContext* aPresContext, nsFormControlFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aDimensionSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowSize);
/**
* Respond to a gui event
* @see nsIFrame::HandleEvent
*/
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
/**
* Draw this frame within the context of a presentation context and rendering context
* @see nsIFrame::Paint
*/
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus);
/**
* Respond to the request to resize and/or reflow
* @see nsIFrame::Reflow
*/
NS_IMETHOD Reflow(nsIPresContext& aCX,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
// new behavior
/**
* Get the class id of the widget associated with this frame
* @return the class id
*/
virtual const nsIID& GetCID();
/**
* Get the interface id of widget associated with this frame
* @return the interface id
*/
virtual const nsIID& GetIID();
NS_IMETHOD GetType(PRInt32* aType) const;
NS_IMETHOD GetName(nsString* aName);
NS_IMETHOD GetValue(nsString* aName);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
/**
* Get the widget associated with this frame
* @param aView the view associated with the frame. It is a convience parm.
* @param aWidget the address of address of where the widget will be placed.
* This method doses an AddRef on the widget.
*/
nsresult GetWidget(nsIView* aView, nsIWidget** aWidget);
nsresult GetWidget(nsIWidget** aWidget);
/**
* Respond to a enter key being pressed
*/
virtual void EnterPressed(nsIPresContext& aPresContext) {}
/**
* Respond to a mouse click (e.g. mouse enter, mouse down, mouse up)
*/
virtual void MouseClicked(nsIPresContext* aPresContext) {}
/**
* Perform opertations after the widget associated with this frame has been
* created.
*/
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual void Reset();
virtual PRBool IsSuccessful();
/**
* Perform opertations before the widget associated with this frame has been
* created.
*/
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
const nsString& aString, nsSize& aSize);
static nscoord GetTextSize(nsIPresContext& aContext, nsFormControlFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize);
void GetWidgetSize(nsSize& aSize) const { aSize.width = mWidgetSize.width;
aSize.height = mWidgetSize.height; }
// XXX similar functionality needs to be added to widget library and these
// need to change to use it.
static nscoord GetScrollbarWidth(float aPixToTwip);
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
NS_IMETHOD GetSize(PRInt32* aSize) const;
NS_IMETHOD GetMaxLength(PRInt32* aSize);
virtual void SetClickPoint(nscoord aX, nscoord aY);
nsFormFrame* GetFormFrame() { return mFormFrame; }
virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; }
protected:
virtual ~nsFormControlFrame();
/**
* Get the size that this frame would occupy without any constraints
* @param aPresContext the presentation context
* @param aDesiredSize the size desired by this frame, to be set by this method
* @param aMaxSize the maximum size available for this frame
*/
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize);
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
NS_IMETHOD GetFont(nsIPresContext* aPresContext, nsFont& aFont);
/**
* Get the width and height of this control based on CSS
* @param aPresContext the presentation context
* @param aSize the size that this frame wants, set by this method. values of -1
* for aSize.width or aSize.height indicate unset values.
*/
void GetStyleSize(nsIPresContext& aContext,
const nsReflowState& aReflowState,
nsSize& aSize);
//nscoord GetStyleDim(nsIPresContext& aPresContext, nscoord aMaxDim,
// nscoord aMaxWidth, const nsStyleCoord& aCoord);
nsMouseState mLastMouseState;
nsIWidget* mWidget;
nsSize mWidgetSize;
PRBool mDidInit;
nsPoint mLastClickPoint;
nsFormFrame* mFormFrame;
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
};
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsFormFrame_h___
#define nsFormFrame_h___
#include "nsIFormManager.h"
#include "nsLeafFrame.h"
#include "nsVoidArray.h"
class nsString;
class nsIContent;
class nsIFrame;
class nsIPresContext;
struct nsReflowMetrics;
struct nsReflowState;
class nsFormControlFrame;
class nsRadioControlFrame;
class nsIFormControlFrame;
class nsFormFrame : public nsLeafFrame,
public nsIFormManager
{
public:
nsFormFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual ~nsFormFrame();
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
// nsIFormManager
NS_IMETHOD OnReset();
NS_IMETHOD OnSubmit(nsIPresContext* aPresContext, nsIFrame* aFrame);
// other methods
void OnRadioChecked(nsRadioControlFrame& aRadio);
void Init(nsIPresContext& aPresContext, PRBool aReinit);
PRBool CanSubmit(nsFormControlFrame& aFrame);
NS_IMETHOD GetMethod(PRInt32* aMethod);
NS_IMETHOD GetEnctype(PRInt32* aEnctype);
NS_IMETHOD GetTarget(nsString* aTarget);
NS_IMETHOD GetAction(nsString* aAction);
protected:
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize);
void RemoveRadioGroups();
void ProcessAsURLEncoded(PRBool aIsPost, nsString& aData);
void ProcessAsMultipart(nsString& aData);
static const char* GetFileNameWithinPath(char* aPathName);
// the following are temporary until nspr and/or netlib provide them
static Temp_GetTempDir(char* aTempDirName);
static char* Temp_GenerateTempFileName(PRInt32 aMaxSize, char* aBuffer);
static void Temp_GetContentType(char* aPathName, char* aContentType);
nsVoidArray mFormControls;
nsVoidArray mRadioGroups;
PRBool mInited;
nsIFormControlFrame* mTextSubmitter;
};
#endif // nsFormFrame_h___

Просмотреть файл

@ -1,169 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsHTMLForms_h___
#define nsHTMLForms_h___
#include "nsIHTMLContent.h"
class nsIAtom;
class nsIFormManager;
// fix this
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
// Form and Form Controls
/**
* Construct an object implementing nsIFormManager
* @param aInstancePtrResult the address at which to place the
* address of the new instance.
* @param aTag the html tag which corresponds to the nsIFormManager
* @return NS_OK if the object was successfully constructed.
*/
extern nsresult
NS_NewHTMLForm(nsIFormManager** aInstancePtrResult,
nsIAtom* aTag);
/**
* Construct an object with behavior of an html input button
* @param aInstancePtrResult the address at which to place the
* address of the new instance.
* @param aTag the html tag which corresponds to the nsIFormManager
* @param aManager the form manager which will manage the constructed object
* @return NS_OK if the object was successfully constructed.
*/
extern nsresult
NS_NewHTMLInputButton(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html button to
* be used with a nsInputFile as the browse button.
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputBrowse(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html reset button
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputReset(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html submit button
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputSubmit(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html checkbox
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputCheckbox(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html input file
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputFile(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html input hidden
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputHidden(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html input image
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputImage(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html select
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLOption(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag);
/**
* Construct an nsIHTMLContent with behavior of an html input password
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputPassword(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html input radio
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputRadio(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html select
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLSelect(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html input text
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputText(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html input text that
* serves as the text for an html input file.
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLInputFileText(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
/**
* Construct an nsIHTMLContent with behavior of an html text area
* @see NS_NewHTMLInputButton for parameter and return values
*/
extern nsresult
NS_NewHTMLTextArea(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
#endif /* nsHTMLForms_h___ */

Просмотреть файл

@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIFormControlFrame_h___
#define nsIFormControlFrame_h___
#include "nsISupports.h"
class nsFormFrame;
class nsIPresContext;
class nsString;
// IID for the nsIFormControlFrame class
#define NS_IFORMCONTROLFRAME_IID \
{ 0x38eb3980, 0x4d99, 0x11d2, \
{ 0x80, 0x3f, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
/**
* nsIFormControlFrame is the common interface for frames of form controls. It
* provides a uniform way of creating widgets, resizing, and painting.
* @see nsLeafFrame and its base classes for more info
*/
class nsIFormControlFrame : public nsISupports {
public:
NS_IMETHOD GetType(PRInt32* aType) const = 0;
NS_IMETHOD GetName(nsString* aName) = 0;
virtual void MouseClicked(nsIPresContext* aPresContext) = 0;
virtual void Reset() = 0;
virtual PRBool IsSuccessful() = 0;
virtual PRInt32 GetMaxNumValues() = 0;
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames) = 0;
virtual void SetFormFrame(nsFormFrame* aFrame) = 0;
};
#endif

Просмотреть файл

@ -1,910 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInput.h"
#include "nsIFormManager.h"
#include "nsInputFrame.h"
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsIRenderingContext.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsLeafFrame.h"
#include "nsCSSRendering.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsCoord.h"
#include "nsDebug.h"
#include "nsIWidget.h"
#include "nsHTMLForms.h"
#include "nsStyleConsts.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsITextWidget.h"
#include "nsIHTMLAttributes.h"
#include "nsGenericHTMLElement.h"
#define ALIGN_UNSET PRUint8(-1)
static NS_DEFINE_IID(kSupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
// Note: we inherit a base class operator new that zeros our memory
nsInput::nsInput(nsIAtom* aTag, nsIFormManager* aManager)
: nsHTMLContainer(aTag), mControl()
{
mFormMan = aManager;
if (nsnull != mFormMan) {
NS_ADDREF(mFormMan);
mFormMan->AddFormControl(&mControl);
}
mSize = ATTR_NOTSET;
mAlign = ALIGN_UNSET;
mLastClickPoint.x = -1;
mLastClickPoint.y = -1;
mCanSubmit = PR_FALSE;
}
nsInput::~nsInput()
{
NS_IF_RELEASE(mWidget);
NS_IF_RELEASE(mWidgetSupports);
if (nsnull != mName) {
delete mName;
}
if (nsnull != mValue) {
delete mValue;
}
if (nsnull != mFormMan) {
// prevent mFormMan from decrementing its ref count on us
mFormMan->RemoveFormControl(&mControl, PR_FALSE);
NS_RELEASE(mFormMan);
}
}
void nsInput::SetClickPoint(nscoord aX, nscoord aY)
{
mLastClickPoint.x = aX;
mLastClickPoint.y = aY;
}
PRBool nsInput::GetCanSubmit() const
{
return mCanSubmit;
}
void nsInput::SetCanSubmit(PRBool aFlag)
{
mCanSubmit = aFlag;
}
void nsInput::SetContent(const nsString& aValue)
{
if (nsnull == mValue) {
mValue = new nsString(aValue);
} else {
*mValue = aValue;
}
}
void
nsInput::MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::align, value);
if (eHTMLUnit_Enumerated == value.GetUnit()) {
nsStyleDisplay* display = (nsStyleDisplay*)
aContext->GetMutableStyleData(eStyleStruct_Display);
nsStyleText* text = (nsStyleText*)
aContext->GetMutableStyleData(eStyleStruct_Text);
switch (value.GetIntValue()) {
case NS_STYLE_TEXT_ALIGN_LEFT:
display->mFloats = NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_TEXT_ALIGN_RIGHT:
display->mFloats = NS_STYLE_FLOAT_RIGHT;
break;
default:
text->mVerticalAlign.SetIntValue(value.GetIntValue(), eStyleUnit_Enumerated);
break;
}
}
nsGenericHTMLElement::MapImageAttributesInto(aAttributes, aContext, aPresContext);
nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsInput::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &nsInput::MapAttributesInto;
return NS_OK;
}
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
nsresult nsInput::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (aIID.Equals(kIFormControlIID)) {
AddRef();
*aInstancePtr = (void*) (nsIFormControl *)&mControl;
return NS_OK;
}
if (aIID.Equals(kIDOMHTMLInputElementIID)) {
AddRef();
*aInstancePtr = (void*) (nsIDOMHTMLInputElement *)this;
return NS_OK;
}
return nsHTMLContainer::QueryInterface(aIID, aInstancePtr);
}
nsrefcnt nsInput::AddRef(void)
{
PRInt32 refCnt = mRefCnt; // debugging
return nsHTMLContainer::AddRef();
}
PRBool nsInput::IsSuccessful(nsIFormControl* aSubmitter) const
{
if (nsnull == mName) {
return PR_FALSE;
}
else {
return PR_TRUE;
}
}
nsrefcnt nsInput::Release()
{
--mRefCnt;
if (mRefCnt <= 0) {
delete this;
return 0;
}
if ((mFormMan == nsnull) || (mRefCnt > 1)) {
return mRefCnt;
}
int numSiblings = mFormMan->GetFormControlCount();
PRBool externalRefs = PR_FALSE; // are there external refs to dad or any siblings
if ((int)mFormMan->GetRefCount() > numSiblings) {
externalRefs = PR_TRUE;
} else {
for (int i = 0; i < numSiblings; i++) {
nsIFormControl* sibling = mFormMan->GetFormControlAt(i);
if (sibling->GetRefCount() > 1) {
externalRefs = PR_TRUE;
break;
}
}
}
if (!externalRefs) {
mRefCnt = 0;
delete this;
return 0;
}
return mRefCnt;
}
PRBool
nsInput::IsHidden()
{
return PR_FALSE;
}
void
nsInput::SetWidget(nsIWidget* aWidget)
{
if (aWidget != mWidget) {
NS_IF_RELEASE(mWidget);
NS_IF_ADDREF(aWidget);
mWidget = aWidget;
NS_IF_RELEASE(mWidgetSupports);
mWidget->QueryInterface(kSupportsIID, (void**)&mWidgetSupports);
}
}
nsrefcnt nsInput::GetRefCount() const
{
return mRefCnt;
}
// these do not AddRef
nsIWidget* nsInput::GetWidget()
{
return mWidget;
}
nsISupports* nsInput::GetWidgetSupports()
{
return mWidgetSupports;
}
PRBool nsInput::GetContent(nsString& aResult) const
{
if (nsnull == mValue) {
aResult.SetLength(0);
return PR_FALSE;
} else {
aResult = *mValue;
return PR_TRUE;
}
}
void
nsInput::SetFormManager(nsIFormManager* aFormMan, PRBool aDecrementRef)
{
if (aDecrementRef) {
NS_IF_RELEASE(mFormMan);
}
mFormMan = aFormMan;
NS_IF_ADDREF(aFormMan);
}
nsIFormManager*
nsInput::GetFormManager() const
{
NS_IF_ADDREF(mFormMan);
return mFormMan;
}
/**
* Get the name associated with this form element.
* (note that form elements without names are not submitable).
*/
NS_IMETHODIMP
nsInput::GetName(nsString& aName)
{
if ((nsnull != mName) && (0 != mName->Length())) {
aName = *mName;
}
else {
aName.SetLength(0);
}
return NS_OK;
}
void
nsInput::Reset()
{
}
PRInt32
nsInput::GetMaxNumValues()
{
return 0;
}
PRBool
nsInput::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
aNumValues = 0;
return PR_FALSE;
}
void nsInput::CacheAttribute(const nsString& aValue, nsString*& aLoc)
{
if (nsnull == aLoc) {
aLoc = new nsString(aValue);
} else {
aLoc->SetLength(0);
aLoc->Append(aValue);
}
}
void nsInput::CacheAttribute(const nsString& aValue, PRInt32 aMinValue, PRInt32& aLoc)
{
PRInt32 status;
PRInt32 intVal = aValue.ToInteger(&status);
aLoc = ((NS_OK == status) && (intVal >= aMinValue)) ? intVal : aMinValue;
}
NS_IMETHODIMP
nsInput::SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify)
{
if (aAttribute == nsHTMLAtoms::type) { // You cannot set the type of a form element
;
}
else if (aAttribute == nsHTMLAtoms::name) {
CacheAttribute(aValue, mName);
}
else if (aAttribute == nsHTMLAtoms::size) {
CacheAttribute(aValue, ATTR_NOTSET, mSize);
}
else if (aAttribute == nsHTMLAtoms::value) {
CacheAttribute(aValue, mValue);
}
else if (aAttribute == nsHTMLAtoms::align) {
nsHTMLValue val;
if (ParseAlignParam(aValue, val)) {
mAlign = val.GetIntValue();
// Reflect the attribute into the syle system
return nsHTMLTagContent::SetAttribute(aAttribute, val, aNotify); // is this needed? YES
} else {
mAlign = ALIGN_UNSET;
}
}
// XXX the following is necessary so that MapAttributesInto gets called
return nsInputSuper::SetAttribute(aAttribute, aValue, aNotify);
}
nsresult nsInput::GetCacheAttribute(nsString* const& aLoc, nsHTMLValue& aValue) const
{
aValue.Reset();
if (nsnull == aLoc) {
return NS_CONTENT_ATTR_NOT_THERE;
}
else {
aValue.SetStringValue(*aLoc);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
nsresult
nsInput::GetCacheAttribute(PRInt32 aLoc, nsHTMLValue& aValue,
nsHTMLUnit aUnit) const
{
aValue.Reset();
if (aLoc <= ATTR_NOTSET) {
return NS_CONTENT_ATTR_NOT_THERE;
}
else {
if (eHTMLUnit_Pixel == aUnit) {
aValue.SetPixelValue(aLoc);
}
else if (eHTMLUnit_Empty == aUnit) {
if (PRBool(aLoc)) {
aValue.SetEmptyValue();
}
else {
return NS_CONTENT_ATTR_NOT_THERE;
}
}
else {
aValue.SetIntValue(aLoc, aUnit);
}
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
NS_IMETHODIMP
nsInput::GetAttribute(nsIAtom* aAttribute, PRInt32& aValue) const
{
nsHTMLValue htmlValue;
nsresult result = GetAttribute(aAttribute, htmlValue);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
if (eHTMLUnit_Empty == htmlValue.GetUnit()) {
aValue = 1;
}
else if (eHTMLUnit_Pixel == htmlValue.GetUnit()) {
aValue = htmlValue.GetPixelValue();
}
else {
aValue = htmlValue.GetIntValue();
}
return NS_CONTENT_ATTR_HAS_VALUE;
}
else {
aValue = ATTR_NOTSET;
// XXX for bool values, this should return 0
return NS_CONTENT_ATTR_NO_VALUE;
}
}
NS_IMETHODIMP
nsInput::GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aValue) const
{
if (aAttribute == nsHTMLAtoms::type) {
nsAutoString tmp;
GetType(tmp);
if (tmp.Length() == 0) { // derivatives that don't support type return zero length string
return NS_CONTENT_ATTR_NOT_THERE;
}
else {
aValue.SetStringValue(tmp);
return NS_CONTENT_ATTR_HAS_VALUE;
}
}
else if (aAttribute == nsHTMLAtoms::name) {
return GetCacheAttribute(mName, aValue);
}
else if (aAttribute == nsHTMLAtoms::size) {
return GetCacheAttribute(mSize, aValue, eHTMLUnit_Pixel); // XXX pixel or percent??
}
else if (aAttribute == nsHTMLAtoms::value) {
return GetCacheAttribute(mValue, aValue);
}
else if (aAttribute == nsHTMLAtoms::align) {
return GetCacheAttribute(mAlign, aValue, eHTMLUnit_Enumerated);
}
else {
return nsInputSuper::GetAttribute(aAttribute, aValue);
}
}
PRBool nsInput::GetChecked(PRBool aGetInitialValue) const
{
return PR_FALSE;
}
void nsInput::SetChecked(PRBool aState, PRBool aSetInitialValue)
{
}
NS_IMETHODIMP
nsInput::GetDefaultValue(nsString& aDefaultValue)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::value, aDefaultValue);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetDefaultValue(const nsString& aDefaultValue)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::value, aDefaultValue, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetDefaultChecked(PRBool* aDefaultChecked)
{
*aDefaultChecked = GetChecked(PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetDefaultChecked(PRBool aDefaultChecked)
{
SetChecked(aDefaultChecked, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetForm(nsIDOMHTMLFormElement** aForm)
{
static NS_DEFINE_IID(kIDOMHTMLFormElementIID, NS_IDOMHTMLFORMELEMENT_IID);
if (nsnull != mFormMan) {
return mFormMan->QueryInterface(kIDOMHTMLFormElementIID, (void **)aForm);
}
*aForm = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetAccept(nsString& aAccept)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::accept, aAccept);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetAccept(const nsString& aAccept)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::accept, aAccept, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetAccessKey(nsString& aAccessKey)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::accesskey, aAccessKey);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetAccessKey(const nsString& aAccessKey)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::accesskey, aAccessKey, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetAlign(nsString& aAlign)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::align, aAlign);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetAlign(const nsString& aAlign)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::align, aAlign, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetAlt(nsString& aAlt)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::alt, aAlt);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetAlt(const nsString& aAlt)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::alt, aAlt, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetChecked(PRBool* aChecked)
{
*aChecked = GetChecked(PR_FALSE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetChecked(PRBool aChecked)
{
SetChecked(aChecked, PR_FALSE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetDisabled(PRBool* aDisabled)
{
nsAutoString result;
*aDisabled = (PRBool)(NS_CONTENT_ATTR_HAS_VALUE == ((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::disabled, result));
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetDisabled(PRBool aDisabled)
{
if (PR_TRUE == aDisabled) {
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::disabled, "", PR_TRUE);
}
else {
UnsetAttribute(nsHTMLAtoms::disabled);
}
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetMaxLength(PRInt32* aMaxLength)
{
nsHTMLValue val;
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::maxlength, val);
*aMaxLength = val.GetIntValue();
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetMaxLength(PRInt32 aMaxLength)
{
nsHTMLValue val;
val.SetIntValue(aMaxLength, eHTMLUnit_Integer);
((nsHTMLTagContent *)this)->SetAttribute(nsHTMLAtoms::maxlength, val, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetName(const nsString& aName)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::name, aName, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetReadOnly(PRBool* aReadOnly)
{
nsAutoString result;
*aReadOnly = (PRBool)(NS_CONTENT_ATTR_HAS_VALUE == ((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::readonly, result));
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetReadOnly(PRBool aReadOnly)
{
if (PR_TRUE == aReadOnly) {
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::readonly, "", PR_TRUE);
}
else {
UnsetAttribute(nsHTMLAtoms::readonly);
}
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetSize(nsString& aSize)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::size, aSize);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetSize(const nsString& aSize)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::size, aSize, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetSrc(nsString& aSrc)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::src, aSrc);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetSrc(const nsString& aSrc)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::src, aSrc, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetTabIndex(PRInt32* aTabIndex)
{
nsHTMLValue val;
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::tabindex, val);
*aTabIndex = val.GetIntValue();
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetTabIndex(PRInt32 aTabIndex)
{
nsHTMLValue val;
val.SetIntValue(aTabIndex, eHTMLUnit_Integer);
((nsHTMLTagContent *)this)->SetAttribute(nsHTMLAtoms::tabindex, val, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetType(nsString& aType)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::type, aType);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetUseMap(nsString& aUseMap)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::usemap, aUseMap);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetUseMap(const nsString& aUseMap)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::usemap, aUseMap, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::GetValue(nsString& aValue)
{
((nsHTMLContainer *)this)->GetAttribute(nsHTMLAtoms::value, aValue);
return NS_OK;
}
NS_IMETHODIMP
nsInput::SetValue(const nsString& aValue)
{
((nsHTMLContainer *)this)->SetAttribute(nsHTMLAtoms::value, aValue, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsInput::Blur()
{
if (nsnull != mWidget) {
nsIWidget *mParentWidget = mWidget->GetParent();
if (nsnull != mParentWidget) {
mParentWidget->SetFocus();
NS_RELEASE(mParentWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsInput::Focus()
{
if (nsnull != mWidget) {
mWidget->SetFocus();
}
return NS_OK;
}
NS_IMETHODIMP
nsInput::Select()
{
if (nsnull != mWidget) {
nsITextWidget *mTextWidget;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID, (void**)&mTextWidget)) {
mTextWidget->SelectAll();
NS_RELEASE(mTextWidget);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsInput::Click()
{
//XXX TBI
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsInput::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
{
nsresult res = NS_OK;
if (nsnull == mScriptObject) {
res = NS_NewScriptHTMLInputElement(aContext, (nsISupports *)(nsIDOMHTMLInputElement *)this, mParent, (void**)&mScriptObject);
}
*aScriptObject = mScriptObject;
return res;
}
//----------------------------------------------------------------------
#define GET_OUTER() ((nsInput*) ((char*)this - nsInput::GetOuterOffset()))
nsInput::AggInputControl::AggInputControl()
{
}
nsInput::AggInputControl::~AggInputControl()
{
}
nsrefcnt nsInput::AggInputControl::AddRef()
{
return GET_OUTER()->AddRef();
}
nsrefcnt nsInput::AggInputControl::Release()
{
return GET_OUTER()->Release();
}
nsresult nsInput::AggInputControl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
return GET_OUTER()->QueryInterface(aIID, aInstancePtr);
}
nsresult nsInput::AggInputControl::GetName(nsString& aName)
{
return GET_OUTER()->GetName(aName);
}
PRInt32 nsInput::AggInputControl::GetMaxNumValues()
{
return GET_OUTER()->GetMaxNumValues();
}
PRBool nsInput::AggInputControl::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
return GET_OUTER()->GetNamesValues(aMaxNumValues, aNumValues, aValues, aNames);
}
void nsInput::AggInputControl::Reset()
{
GET_OUTER()->Reset();
}
void nsInput::AggInputControl::SetFormManager(nsIFormManager* aFormMan, PRBool aDecrementRef)
{
GET_OUTER()->SetFormManager(aFormMan, aDecrementRef);
}
nsIFormManager* nsInput::AggInputControl::GetFormManager() const
{
return GET_OUTER()->GetFormManager();
}
nsrefcnt nsInput::AggInputControl::GetRefCount() const
{
return GET_OUTER()->GetRefCount();
}
PRBool nsInput::AggInputControl::GetChecked(PRBool aGetInitialValue) const
{
return GET_OUTER()->GetChecked(aGetInitialValue);
}
void nsInput::AggInputControl::SetChecked(PRBool aState, PRBool aSetInitialValue)
{
GET_OUTER()->SetChecked(aState, aSetInitialValue);
}
void nsInput::AggInputControl::GetType(nsString& aName) const
{
GET_OUTER()->GetType(aName);
}
PRBool nsInput::AggInputControl::IsSuccessful(nsIFormControl* aSubmitter) const
{
return GET_OUTER()->IsSuccessful(aSubmitter);
}
void nsInput::AggInputControl::SetContent(const nsString& aValue)
{
GET_OUTER()->SetContent(aValue);
}
PRBool nsInput::AggInputControl::GetContent(nsString& aResult) const
{
return GET_OUTER()->GetContent(aResult);
}
void nsInput::AggInputControl::SetCanSubmit(PRBool aFlag)
{
GET_OUTER()->SetCanSubmit(aFlag);
}
PRBool nsInput::AggInputControl::GetCanSubmit() const
{
return GET_OUTER()->GetCanSubmit();
}

Просмотреть файл

@ -1,697 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInput.h"
#include "nsInputFrame.h"
#include "nsInputFile.h"
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsIRenderingContext.h"
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsIStyleContext.h"
#include "nsLeafFrame.h"
#include "nsCSSRendering.h"
#include "nsHTMLIIDs.h"
#include "nsIButton.h"
#include "nsIViewManager.h"
#include "nsISupports.h"
#include "nsHTMLAtoms.h"
#include "nsIButton.h"
#include "nsIView.h"
#include "nsViewsCID.h"
#include "nsWidgetsCID.h"
#include "nsIDeviceContext.h"
#include "nsIFontCache.h"
#include "nsIFontMetrics.h"
#include "nsIFormManager.h"
#include "nsIImage.h"
#include "nsHTMLForms.h"
#include "nsHTMLImage.h"
#include "nsStyleUtil.h"
#include "nsDOMEvent.h"
#include "nsStyleConsts.h"
#include "nsIHTMLAttributes.h"
#include "nsGenericHTMLElement.h"
enum nsButtonTagType {
kButtonTag_Button,
kButtonTag_Input
};
enum nsButtonType {
kButton_Button,
kButton_Reset,
kButton_Submit,
kButton_Image,
kButton_Hidden,
kButton_Browse
};
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIButtonIID, NS_IBUTTON_IID);
typedef nsInput nsInputButtonSuper;
class nsInputButton : public nsInputButtonSuper {
public:
nsInputButton (nsIAtom* aTag, nsIFormManager* aManager,
nsButtonType aType);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const;
nsButtonType GetButtonType() { return mType; }
nsButtonTagType GetButtonTagType() { return mTagType; }
virtual void GetDefaultLabel(nsString& aLabel);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual PRBool IsHidden();
virtual PRBool IsSuccessful(nsIFormControl* aSubmitter) const;
protected:
virtual ~nsInputButton();
virtual void GetType(nsString& aResult) const;
nsButtonType mType;
nsButtonTagType mTagType;
};
class nsInputButtonFrame : public nsInputFrame {
public:
typedef nsInputFrame nsInputButtonFrameSuper;
nsInputButtonFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView* aView);
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
nsButtonType GetButtonType() const;
nsButtonTagType GetButtonTagType() const;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
protected:
virtual ~nsInputButtonFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
nsHTMLImageLoader mImageLoader;
};
// nsInputButton Implementation
nsInputButton::nsInputButton(nsIAtom* aTag, nsIFormManager* aManager,
nsButtonType aType)
: nsInput(aTag, aManager), mType(aType)
{
nsAutoString tagName;
aTag->ToString(tagName);
mTagType = (tagName.EqualsIgnoreCase("input")) ? kButtonTag_Input : kButtonTag_Button;
}
nsInputButton::~nsInputButton()
{
}
PRBool nsInputButton::IsSuccessful(nsIFormControl* aSubmitter) const
{
if ((kButton_Hidden == mType) || ((void*)&mControl == (void*)aSubmitter)) {
return nsInputButtonSuper::IsSuccessful(aSubmitter);
}
return PR_FALSE;
}
PRBool
nsInputButton::IsHidden()
{
if (kButton_Hidden == mType) {
return PR_TRUE;
}
else {
return PR_FALSE;
}
}
void nsInputButton::GetType(nsString& aResult) const
{
aResult.SetLength(0);
if (kButtonTag_Button == mTagType) {
aResult.Append("button");
return;
}
// XXX put these and other literals into statics (e.g. gBUTTON_TYPE)
switch (mType) {
case kButton_Button:
aResult.Append("button");
break;
case kButton_Reset:
aResult.Append("reset");
break;
case kButton_Image:
aResult.Append("image");
break;
case kButton_Hidden:
aResult.Append("hidden");
break;
case kButton_Browse:
aResult.Append("browse");
break;
case kButton_Submit:
default:
aResult.Append("submit");
break;
}
}
void
nsInputButton::GetDefaultLabel(nsString& aString)
{
if (kButton_Reset == mType) {
aString = "Reset";
} else if (kButton_Submit == mType) {
aString = "Submit Query";
} else if (kButton_Browse == mType) {
aString = "Browse...";
} else {
aString = " ";
}
}
PRInt32
nsInputButton::GetMaxNumValues()
{
if ((kButton_Submit == mType) || (kButton_Hidden == mType)) {
return 1;
} else if ((kButton_Image == mType) && (kButtonTag_Input == mTagType)) {
return 2;
} else {
return 0;
}
}
PRBool
nsInputButton::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if ((aMaxNumValues <= 0) || (nsnull == mName)) {
return PR_FALSE;
}
if ((kButton_Image == mType) && (kButtonTag_Input == mTagType)) {
char buf[20];
aNumValues = 2;
aValues[0].SetLength(0);
sprintf(&buf[0], "%d", mLastClickPoint.x);
aValues[0].Append(&buf[0]);
aNames[0] = *mName;
aNames[0].Append(".x");
aValues[1].SetLength(0);
sprintf(&buf[0], "%d", mLastClickPoint.y);
aValues[1].Append(&buf[0]);
aNames[1] = *mName;
aNames[1].Append(".y");
return PR_TRUE;
}
else if (((kButton_Submit == mType) || (kButton_Hidden == mType)) && (nsnull != mValue)) { // XXX fix this in branch
aValues[0] = *mValue;
aNames[0] = *mName;
aNumValues = 1;
return PR_TRUE;
} else {
aNumValues = 0;
return PR_FALSE;
}
}
NS_IMETHODIMP
nsInputButton::SetAttribute(nsIAtom* aAttribute, const nsString& aString,
PRBool aNotify)
{
nsHTMLValue val;
if (ParseImageProperty(aAttribute, aString, val)) {
return nsHTMLTagContent::SetAttribute(aAttribute, val, aNotify);
}
return nsInputButtonSuper::SetAttribute(aAttribute, aString, aNotify);
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
nsHTMLValue value;
aAttributes->GetAttribute(nsHTMLAtoms::type, value);
if (eHTMLUnit_String == value.GetUnit()) { // XXX thiws should be parses in AttributeToString
nsAutoString val;
value.GetStringValue(val);
if (val.EqualsIgnoreCase("image")) {
// Apply the image border as well. For form elements the color is
// always forced to blue.
static nscolor blue[4] = {
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255),
NS_RGB(0, 0, 255)
};
nsGenericHTMLElement::MapImageBorderAttributesInto(aAttributes, aContext, aPresContext, blue);
}
}
nsInputButtonSuper::MapAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsInputButton::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
//----------------------------------------------------------------------
// nsInputButtonFrame Implementation
nsresult
NS_NewInputButtonFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputButtonFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputButtonFrame::nsInputButtonFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{
}
nsInputButtonFrame::~nsInputButtonFrame()
{
}
nsButtonType
nsInputButtonFrame::GetButtonType() const
{
nsInputButton* button = (nsInputButton *)mContent;
return button->GetButtonType();
}
nsButtonTagType
nsInputButtonFrame::GetButtonTagType() const
{
nsInputButton* button = (nsInputButton *)mContent;
return button->GetButtonTagType();
}
nscoord nsInputButtonFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(4, aPixToTwip);
}
nscoord nsInputButtonFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
nscoord nsInputButtonFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
//return NSIntPixelsToTwips(4, aPixToTwip);
#ifdef XP_PC
return (nscoord)NSToIntRound((float)aInnerHeight * 0.25f);
#endif
#ifdef XP_UNIX
return (nscoord)NSToIntRound((float)aInnerHeight * 0.50f);
#endif
}
nscoord nsInputButtonFrame::GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
#ifdef XP_PC
if (kBackwardMode == GetMode()) {
return (nscoord)NSToIntRound(float(aInnerWidth) * 0.25f);
} else {
return NSIntPixelsToTwips(10, aPixToTwip) + 8;
}
#endif
#ifdef XP_UNIX
if (kBackwardMode == GetMode()) {
return (nscoord)NSToIntRound(float(aInnerWidth) * 0.5f);
} else {
return NSIntPixelsToTwips(20, aPixToTwip);
}
#endif
}
NS_METHOD nsInputButtonFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mVisible) {
// let super do processing if there is no image
if (kButton_Image != GetButtonType()) {
return nsInputButtonFrameSuper::Paint(aPresContext, aRenderingContext,
aDirtyRect);
}
// First paint background and borders
nsInputButtonFrameSuper::Paint(aPresContext, aRenderingContext, aDirtyRect);
nsIImage* image = mImageLoader.GetImage();
if (nsnull == image) {
// No image yet
return NS_OK;
}
// Now render the image into our inner area (the area without the
nsRect inner;
GetInnerArea(&aPresContext, inner);
aRenderingContext.DrawImage(image, inner);
}
return NS_OK;
}
void
nsInputButtonFrame::MouseClicked(nsIPresContext* aPresContext)
{
nsInputButton* button = (nsInputButton *)mContent;
nsButtonType butType = button->GetButtonType();
nsButtonTagType butTagType = button->GetButtonTagType();
nsIFormManager* formMan = button->GetFormManager();
if (nsnull != formMan) {
if (kButton_Reset == butType) {
//Send DOM event
nsEventStatus mStatus;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_RESET;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
formMan->OnReset();
}
else if ((kButton_Submit == butType) ||
((kButton_Image == butType) && (kButtonTag_Input == butTagType))) {
//NS_ADDREF(this);
//Send DOM event
nsEventStatus mStatus;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
nsIFormControl* control;
mContent->QueryInterface(kIFormControlIID, (void**)&control);
formMan->OnSubmit(aPresContext, this, control);
//NS_RELEASE(this);
NS_IF_RELEASE(control);
}
NS_RELEASE(formMan);
} else if (kButton_Browse == butType) {
((nsInputFileFrame *)mContentParent)->MouseClicked(aPresContext);
}
}
NS_METHOD
nsInputButtonFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if ((kButtonTag_Input == GetButtonTagType()) &&
(kButton_Image == GetButtonType())) {
nsSize ignore;
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, ignore);
AddBordersAndPadding(&aPresContext, aDesiredSize);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
else {
return nsInputButtonFrameSuper::
Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
}
}
void
nsInputButtonFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
if (kButton_Hidden == GetButtonType()) { // there is no physical rep
aDesiredLayoutSize.width = 0;
aDesiredLayoutSize.height = 0;
aDesiredLayoutSize.ascent = 0;
aDesiredLayoutSize.descent = 0;
}
else {
if (kButton_Image == GetButtonType()) { // there is an image
// Setup url before starting the image load
nsAutoString src;
if (NS_CONTENT_ATTR_HAS_VALUE == mContent->GetAttribute("SRC", src)) {
mImageLoader.SetURL(src);
}
mImageLoader.GetDesiredSize(aPresContext, aReflowState, aDesiredLayoutSize);
}
else { // there is a widget
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
// a browse button shares is style context with its parent nsInputFile
// it uses everything from it except width
if (kButton_Browse == GetButtonType()) {
styleSize.width = CSS_NOTSET;
}
nsSize size;
PRBool widthExplicit, heightExplicit;
PRInt32 ignore;
nsInputButton* button = (nsInputButton *)mContent;
nsAutoString defaultLabel;
button->GetDefaultLabel(defaultLabel);
nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value,
&defaultLabel, 1, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, spec, size,
widthExplicit, heightExplicit, ignore);
aDesiredLayoutSize.width = size.width;
aDesiredLayoutSize.height= size.height;
}
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
}
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height= aDesiredLayoutSize.height;
}
void
nsInputButtonFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
{
nsInputButton* content;
GetContent((nsIContent*&) content);
nsIWidget* widget = nsnull;
nsIButton* button = nsnull;
nsresult result = GetWidget(aView, &widget);
if (result == NS_OK) {
widget->QueryInterface(kIButtonIID,(void**)&button);
if (kButton_Browse != content->GetButtonType()) { // browse button always uses default
const nsStyleFont* styleFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
if ((styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT) ||
(styleFont->mFlags & NS_STYLE_FONT_SIZE_EXPLICIT)) {
nsFont widgetFont(styleFont->mFixedFont);
widgetFont.weight = NS_FONT_WEIGHT_NORMAL; // always normal weight
widgetFont.size = styleFont->mFont.size; // normal font size
if (0 == (styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT)) {
widgetFont.name = "Arial"; // XXX windows specific font
}
widget->SetFont(widgetFont);
}
else {
// use arial, scaled down one HTML size
// italics, decoration & variant(?) get used
nsFont widgetFont(styleFont->mFont);
widgetFont.name = "Arial"; // XXX windows specific font
widgetFont.weight = NS_FONT_WEIGHT_NORMAL;
const nsFont& normal = aPresContext->GetDefaultFont();
PRInt32 scaler = aPresContext->GetFontScaler();
float scaleFactor = nsStyleUtil::GetScalingFactor(scaler);
PRInt32 fontIndex = nsStyleUtil::FindNextSmallerFontSize(widgetFont.size, (PRInt32)normal.size, scaleFactor);
widgetFont.size = nsStyleUtil::CalcFontPointSize(fontIndex, (PRInt32)normal.size, scaleFactor);
widget->SetFont(widgetFont);
}
}
}
else {
NS_ASSERTION(0, "no widget in button control");
}
nsString value;
nsresult status = ((nsHTMLTagContent*)content)->GetAttribute(nsHTMLAtoms::value, value);
if (button != nsnull)
{
if (NS_CONTENT_ATTR_HAS_VALUE == status) {
button->SetLabel(value);
}
else {
nsAutoString label;
content->GetDefaultLabel(label);
button->SetLabel(label);
}
}
NS_IF_RELEASE(button);
NS_IF_RELEASE(content);
}
const nsIID&
nsInputButtonFrame::GetIID()
{
static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
return kButtonIID;
}
const nsIID&
nsInputButtonFrame::GetCID()
{
static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
return kButtonCID;
}
nsresult
CreateButton(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager,
nsButtonType aType)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputButton(aTag, aManager, aType);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
nsresult
NS_NewHTMLInputButton(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Button);
}
nsresult
NS_NewHTMLButton(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Button);
}
nsresult
NS_NewHTMLInputSubmit(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Submit);
}
nsresult
NS_NewHTMLInputReset(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Reset);
}
nsresult
NS_NewHTMLInputImage(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Image);
}
nsresult
NS_NewHTMLInputHidden(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
return CreateButton(aInstancePtrResult, aTag, aManager, kButton_Hidden);
}
nsresult
NS_NewHTMLInputBrowse(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
nsresult result = CreateButton(aInstancePtrResult, aTag, aManager, kButton_Browse);
nsAutoString label;
nsInputButton* button = (nsInputButton *)*aInstancePtrResult;
button->GetDefaultLabel(label);
button->SetAttribute(nsHTMLAtoms::value, label, PR_FALSE);
return result;
}

Просмотреть файл

@ -1,321 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInputCheckbox.h"
#include "nsICheckButton.h"
#include "nsInputFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsWidgetsCID.h"
#include "nsIView.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsStyleUtil.h"
static NS_DEFINE_IID(kICheckButtonIID, NS_ICHECKBUTTON_IID);
// Prototypes
nsresult
NS_NewHTMLInputCheckbox(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
class nsInputCheckboxFrame : public nsInputFrame {
public:
nsInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual void MouseClicked(nsIPresContext* aPresContext);
protected:
virtual ~nsInputCheckboxFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewInputCheckboxFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputCheckboxFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputCheckboxFrame::nsInputCheckboxFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{
}
nsInputCheckboxFrame::~nsInputCheckboxFrame()
{
}
const nsIID&
nsInputCheckboxFrame::GetIID()
{
static NS_DEFINE_IID(kCheckboxIID, NS_ICHECKBUTTON_IID);
return kCheckboxIID;
}
const nsIID&
nsInputCheckboxFrame::GetCID()
{
static NS_DEFINE_IID(kCheckboxCID, NS_CHECKBUTTON_CID);
return kCheckboxCID;
}
void
nsInputCheckboxFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
float p2t = aPresContext->GetPixelsToTwips();
#ifdef XP_PC
aDesiredWidgetSize.width = NSIntPixelsToTwips(12, p2t);
aDesiredWidgetSize.height = NSIntPixelsToTwips(12, p2t);
#endif
#ifdef XP_PC
aDesiredWidgetSize.width = NSIntPixelsToTwips(20, p2t);
aDesiredWidgetSize.height = NSIntPixelsToTwips(20, p2t);
#endif
aDesiredLayoutSize.width = aDesiredWidgetSize.width;
aDesiredLayoutSize.height = aDesiredWidgetSize.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
}
void
nsInputCheckboxFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
{
// get the intial state of the checkbox
nsInputCheckbox* content = (nsInputCheckbox *)mContent; // this must be an nsCheckbox
nsHTMLValue value;
nsresult result = content->GetAttribute(nsHTMLAtoms::checked, value);
PRBool checked = (result != NS_CONTENT_ATTR_NOT_THERE) ? PR_TRUE : PR_FALSE;
// set the widget to the initial state
nsIWidget* widget = nsnull;
nsICheckButton* checkbox = nsnull;
if (NS_OK == GetWidget(aView, &widget)) {
widget->QueryInterface(GetIID(),(void**)&checkbox);
checkbox->SetState(checked);
const nsStyleColor* color =
nsStyleUtil::FindNonTransparentBackground(mStyleContext);
if (nsnull != color) {
widget->SetBackgroundColor(color->mBackgroundColor);
}
else {
widget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
}
NS_IF_RELEASE(checkbox);
NS_IF_RELEASE(widget);
}
}
void
nsInputCheckboxFrame::MouseClicked(nsIPresContext* aPresContext)
{
nsIWidget* widget = nsnull;
nsICheckButton* checkbox = nsnull;
nsIView* view;
GetView(view);
if (NS_OK == GetWidget(view, &widget)) {
widget->QueryInterface(GetIID(),(void**)&checkbox);
PRBool oldState;
checkbox->GetState(oldState);
PRBool newState = oldState ? PR_FALSE : PR_TRUE;
checkbox->SetState(newState);
NS_IF_RELEASE(checkbox);
NS_IF_RELEASE(widget);
}
}
// nsInputCheckbox
nsInputCheckbox::nsInputCheckbox(nsIAtom* aTag, nsIFormManager* aManager)
: nsInput(aTag, aManager)
{
mChecked = PR_FALSE;
}
nsInputCheckbox::~nsInputCheckbox()
{
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
float p2t = aPresContext->GetPixelsToTwips();
nscoord pad = NSIntPixelsToTwips(3, p2t);
// add left and right padding around the radio button via css
nsStyleSpacing* spacing = (nsStyleSpacing*) aContext->GetMutableStyleData(eStyleStruct_Spacing);
if (eStyleUnit_Null == spacing->mMargin.GetLeftUnit()) {
nsStyleCoord left(pad);
spacing->mMargin.SetLeft(left);
}
if (eStyleUnit_Null == spacing->mMargin.GetRightUnit()) {
nsStyleCoord right(NSIntPixelsToTwips(5, p2t));
spacing->mMargin.SetRight(right);
}
// add bottom padding if backward mode
// XXX why isn't this working?
nsCompatibility mode;
aPresContext->GetCompatibilityMode(mode);
if (eCompatibility_NavQuirks == mode) {
if (eStyleUnit_Null == spacing->mMargin.GetBottomUnit()) {
nsStyleCoord bottom(pad);
spacing->mMargin.SetBottom(bottom);
}
}
nsInput::MapAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsInputCheckbox::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
PRInt32
nsInputCheckbox::GetMaxNumValues()
{
return 1;
}
PRBool
nsInputCheckbox::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if ((aMaxNumValues <= 0) || (nsnull == mName)) {
return PR_FALSE;
}
nsIWidget* widget = GetWidget();
nsICheckButton* checkBox = nsnull;
if (widget != nsnull && NS_OK == widget->QueryInterface(kICheckButtonIID,(void**)&checkBox))
{
PRBool state = PR_FALSE;
checkBox->GetState(state);
if(PR_TRUE != state) {
return PR_FALSE;
}
if (nsnull == mValue) {
aValues[0] = "on";
} else {
aValues[0] = *mValue;
}
aNames[0] = *mName;
aNumValues = 1;
NS_RELEASE(checkBox);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsInputCheckbox::Reset()
{
nsIWidget* widget = GetWidget();
nsICheckButton* checkBox = nsnull;
if (widget != nsnull && NS_OK == widget->QueryInterface(kICheckButtonIID,(void**)&checkBox))
{
checkBox->SetState(mChecked);
NS_RELEASE(checkBox);
}
}
void nsInputCheckbox::GetType(nsString& aResult) const
{
aResult = "checkbox";
}
NS_IMETHODIMP
nsInputCheckbox::SetAttribute(nsIAtom* aAttribute,
const nsString& aValue,
PRBool aNotify)
{
if (aAttribute == nsHTMLAtoms::checked) {
mChecked = PR_TRUE;
}
return nsInputCheckboxSuper::SetAttribute(aAttribute, aValue, aNotify);
}
NS_IMETHODIMP
nsInputCheckbox::GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const
{
aResult.Reset();
if (aAttribute == nsHTMLAtoms::checked) {
return GetCacheAttribute(mChecked, aResult, eHTMLUnit_Empty);
}
else {
return nsInputCheckboxSuper::GetAttribute(aAttribute, aResult);
}
}
nsresult
NS_NewHTMLInputCheckbox(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputCheckbox(aTag, aManager);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}

Просмотреть файл

@ -1,54 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsInputCheckbox_h___
#define nsInputCheckbox_h___
#include "nsInput.h"
class nsIAtom;
class nsString;
class nsInputCheckbox : public nsInput {
public:
typedef nsInput nsInputCheckboxSuper;
nsInputCheckbox (nsIAtom* aTag, nsIFormManager* aManager);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
NS_IMETHOD GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const;
virtual void Reset();
protected:
virtual ~nsInputCheckbox();
virtual void GetType(nsString& aResult) const;
PRBool mChecked; // initial checked flag value
};
#endif

Просмотреть файл

@ -1,314 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInput.h"
#include "nsInputFrame.h"
#include "nsInputFile.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLForms.h"
#include "nsIFileWidget.h"
#include "nsITextWidget.h"
#include "nsWidgetsCID.h"
#include "nsRepository.h"
#include "nsIView.h"
#include "nsHTMLParts.h"
PRInt32 nsInputFileFrame::gSpacing = 40;
nsString* nsInputFile::gFILE_TYPE = new nsString("file");
nsresult
NS_NewInputFileFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputFileFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputFileFrame::nsInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsHTMLContainerFrame(aContent, aParentFrame)
{
}
nsInputFileFrame::~nsInputFileFrame()
{
}
// XXX this should be removed when nsView exposes it
nsIWidget*
GetWindowTemp(nsIView *aView)
{
nsIWidget *window = nsnull;
nsIView *ancestor = aView;
while (nsnull != ancestor) {
ancestor->GetWidget(window);
if (nsnull != window) {
return window;
}
ancestor->GetParent(ancestor);
}
return nsnull;
}
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
// this is in response to the MouseClick from the containing browse button
// XXX still need to get filters from accept attribute
void nsInputFileFrame::MouseClicked(nsIPresContext* aPresContext)
{
nsInputFrame* textFrame = (nsInputFrame *)mFirstChild;
nsITextWidget* textWidget;
nsIView* textView;
textFrame->GetView(textView);
if (nsnull == textView) {
return;
}
if (NS_OK != textFrame->GetWidget(textView, (nsIWidget **)&textWidget)) {
return;
}
nsIView* parentView;
textView->GetParent(parentView);
nsIWidget* parentWidget = GetWindowTemp(parentView);
nsIFileWidget *fileWidget;
nsString title("FileWidget Title <here> mode = save");
nsRepository::CreateInstance(kCFileWidgetCID, nsnull, kIFileWidgetIID, (void**)&fileWidget);
nsString titles[] = {"all files"};
nsString filters[] = {"*.*"};
fileWidget->SetFilterList(1, titles, filters);
fileWidget->Create(parentWidget, title, eMode_load, nsnull, nsnull);
PRUint32 result = fileWidget->Show();
if (result) {
PRUint32 size;
nsString fileName;
fileWidget->GetFile(fileName);
((nsITextWidget *)textWidget)->SetText(fileName,size);
}
NS_RELEASE(fileWidget);
NS_RELEASE(parentWidget);
NS_RELEASE(textWidget);
}
NS_IMETHODIMP nsInputFileFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsInputFile* content = (nsInputFile*)mContent;
nsIFrame* childFrame;
if (nsnull == mFirstChild) {
// XXX This code should move to Init(), someday when the frame construction
// changes are all done and Init() is always getting called...
nsInputText* textField = content->GetTextField();
nsInput* browseButton = content->GetBrowseButton();
if ((nsnull != textField) && (nsnull != browseButton)) {
NS_NewInputTextFrame(textField, this, childFrame);
childFrame->SetStyleContext(&aPresContext, mStyleContext);
mFirstChild = childFrame;
NS_NewInputButtonFrame(browseButton, this, childFrame);
childFrame->SetStyleContext(&aPresContext, mStyleContext);
mFirstChild->SetNextSibling(childFrame);
mChildCount = 2;
}
NS_IF_RELEASE(textField);
NS_IF_RELEASE(browseButton);
}
nsSize maxSize = aReflowState.maxSize;
nsReflowMetrics desiredSize = aDesiredSize;
aDesiredSize.width = gSpacing;
aDesiredSize.height = 0;
childFrame = mFirstChild;
nsPoint offset(0,0);
while (nsnull != childFrame) { // reflow, place, size the children
nsReflowState reflowState(childFrame, aReflowState, maxSize);
childFrame->WillReflow(aPresContext);
nsresult result = childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus);
NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
nsRect rect(offset.x, offset.y, desiredSize.width, desiredSize.height);
childFrame->SetRect(rect);
maxSize.width -= desiredSize.width;
aDesiredSize.width += desiredSize.width;
aDesiredSize.height = desiredSize.height;
childFrame->GetNextSibling(childFrame);
offset.x += desiredSize.width + gSpacing;
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
PRIntn
nsInputFileFrame::GetSkipSides() const
{
return 0;
}
//----------------------------------------------------------------------
// nsInputFile
nsInputFile::nsInputFile(nsIAtom* aTag, nsIFormManager* aManager)
: nsInput(aTag, aManager)
{
mTextField = nsnull;
mBrowseButton = nsnull;
}
nsInputFile::~nsInputFile()
{
NS_IF_RELEASE(mTextField);
NS_IF_RELEASE(mBrowseButton);
}
nsInputText* nsInputFile::GetTextField()
{
NS_IF_ADDREF(mTextField);
return mTextField;
}
void nsInputFile::SetTextField(nsInputText* aTextField)
{
NS_IF_RELEASE(mTextField);
NS_IF_ADDREF(aTextField);
mTextField = aTextField;
}
nsInput* nsInputFile::GetBrowseButton()
{
NS_IF_ADDREF(mBrowseButton);
return mBrowseButton;
}
void nsInputFile::SetBrowseButton(nsInput* aBrowseButton)
{
NS_IF_RELEASE(mBrowseButton);
NS_IF_ADDREF(aBrowseButton);
mBrowseButton = aBrowseButton;
}
void nsInputFile::GetType(nsString& aResult) const
{
aResult = "file";
}
PRInt32
nsInputFile::GetMaxNumValues()
{
return 1;
}
PRBool
nsInputFile::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if ((aMaxNumValues <= 0) || (nsnull == mName)) {
return PR_FALSE;
}
// use our name and the text widgets value
aNames[0] = *mName;
nsIWidget* widget = mTextField->GetWidget();
nsITextWidget* textWidget = nsnull;
if (widget != nsnull && NS_OK == widget->QueryInterface(kITextWidgetIID,(void**)textWidget))
{
PRUint32 actualSize;
textWidget->GetText(aValues[0], 0, actualSize);
aNumValues = 1;
NS_RELEASE(textWidget);
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP
nsInputFile::SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify)
{
// get the text and set its relevant attributes
if ((aAttribute == nsHTMLAtoms::size) || (aAttribute == nsHTMLAtoms::maxlength) ||
(aAttribute == nsHTMLAtoms::value) ||
(aAttribute == nsHTMLAtoms::disabled) || (aAttribute == nsHTMLAtoms::readonly))
{
mTextField->SetAttribute(aAttribute, aValue, aNotify);
}
return nsInputFileSuper::SetAttribute(aAttribute, aValue, aNotify);
}
nsresult
NS_NewHTMLInputFile(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsInputFile* inputFile = new nsInputFile(aTag, aManager);
if (nsnull == inputFile) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsInputText* textField;
// pass in a null form manager, since this text field is not part of the content model
nsresult status = NS_NewHTMLInputText((nsIHTMLContent**)&textField, aTag, nsnull);
if (NS_OK != status) {
return NS_ERROR_OUT_OF_MEMORY;
}
inputFile->SetTextField(textField);
NS_RELEASE(textField);
nsInput* browseButton;
// pass in a null form manager, since this browse button is not part of the content model
status = NS_NewHTMLInputBrowse((nsIHTMLContent**)&browseButton, aTag, nsnull);
if (NS_OK != status) {
return NS_ERROR_OUT_OF_MEMORY;
}
inputFile->SetBrowseButton(browseButton);
NS_RELEASE(browseButton);
return inputFile->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}

Просмотреть файл

@ -1,77 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsInputFile_h___
#define nsInputFile_h___
#include "nsInput.h"
#include "nsHTMLContainerFrame.h"
#include "nsInputFrame.h"
#include "nsInputText.h"
class nsIAtom;
class nsString;
// this class definition will move to nsInputFile.cpp
class nsInputFileFrame : public nsHTMLContainerFrame {
public:
nsInputFileFrame(nsIContent* aContent, nsIFrame* aParentFrame);
NS_IMETHOD Reflow(nsIPresContext& aCX,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
virtual void MouseClicked(nsIPresContext* aPresContext);
static PRInt32 gSpacing;
protected:
virtual ~nsInputFileFrame();
virtual PRIntn GetSkipSides() const;
};
class nsInputFile : public nsInput {
public:
typedef nsInput nsInputFileSuper;
static nsString* gFILE_TYPE;
nsInputFile (nsIAtom* aTag, nsIFormManager* aManager);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
nsInputText* GetTextField();
void SetTextField(nsInputText* aTextField);
nsInput* GetBrowseButton();
void SetBrowseButton(nsInput* aBrowseButton);
protected:
virtual ~nsInputFile();
virtual void GetType(nsString& aResult) const;
nsInputText* mTextField;
nsInput* mBrowseButton; // XXX don't have type safety until nsInputButton is exposed
//PRInt32 mMaxLength;
};
#endif

Просмотреть файл

@ -1,693 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInput.h"
#include "nsInputFrame.h"
#include "nsHTMLParts.h"
#include "nsHTMLContainer.h"
#include "nsIRenderingContext.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIStyleContext.h"
#include "nsLeafFrame.h"
#include "nsCSSRendering.h"
#include "nsHTMLIIDs.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsCoord.h"
#include "nsWidgetsCID.h"
#include "nsViewsCID.h"
#include "nsRepository.h"
#include "nsGUIEvent.h"
#include "nsDOMEvent.h"
#include "nsIFontCache.h"
#include "nsIFontMetrics.h"
#include "nsIFormManager.h"
#include "nsIDeviceContext.h"
#include "nsHTMLAtoms.h"
#include "nsIButton.h" // remove this when GetCID is pure virtual
#include "nsICheckButton.h" //remove this
#include "nsITextWidget.h" //remove this
#include "nsISupports.h"
#include "nsHTMLForms.h"
#include "nsStyleConsts.h"
#include "nsUnitConversion.h"
#include "nsCSSLayout.h"
#include "nsStyleUtil.h"
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
nsInputFrame::nsInputFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInputFrameSuper(aContent, aParentFrame)
{
mLastMouseState = eMouseNone;
mDidInit = PR_FALSE;
}
nsInputFrame::~nsInputFrame()
{
//printf("nsInputFrame::~nsInputFrame \n");
}
NS_METHOD nsInputFrame::SetRect(const nsRect& aRect)
{
return nsInputFrameSuper::SetRect(aRect);
}
nsFormRenderingMode nsInputFrame::GetMode() const
{
nsInput* content = (nsInput *)mContent;
nsIFormManager* formMan = content->GetFormManager();
if (formMan) {
nsFormRenderingMode mode = formMan->GetMode();
NS_RELEASE(formMan);
return mode;
}
else {
return kBackwardMode;
}
}
nscoord nsInputFrame::GetScrollbarWidth(float aPixToTwip)
{
return NSIntPixelsToTwips(19, aPixToTwip); // XXX this is windows
}
nscoord nsInputFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(3, aPixToTwip);
}
nscoord nsInputFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
nscoord nsInputFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
return NSIntPixelsToTwips(3, aPixToTwip);
}
nscoord nsInputFrame::GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
return GetVerticalInsidePadding(aPixToTwip, aInnerWidth);
}
// XXX it would be cool if form element used our rendering sw, then
// they could be blended, and bordered, and so on...
NS_METHOD
nsInputFrame::Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
{
const nsStyleDisplay* disp =
(const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (disp->mVisible) {
// Make sure the widget is visible if it isn't currently visible
nsIView* view = nsnull;
GetView(view);
if (nsnull != view) {
if (PR_FALSE == mDidInit) {
nsIFormManager* formMan = ((nsInput*)mContent)->GetFormManager();
if (formMan) {
formMan->Init(PR_FALSE);
NS_RELEASE(formMan);
}
PostCreateWidget(&aPresContext, view);
mDidInit = PR_TRUE;
}
// SetViewVisiblity(&aPresContext, PR_TRUE);
}
// Point borders/padding if any
return nsInputFrameSuper::Paint(aPresContext, aRenderingContext, aDirtyRect);
}
return NS_OK;
}
//don't call this. MMP
void
nsInputFrame::SetViewVisiblity(nsIPresContext* aPresContext, PRBool aShow)
{
nsIView* view = nsnull;
GetView(view);
if (nsnull != view) {
nsIWidget* widget;
nsresult result = GetWidget(view, &widget);
if (NS_OK == result) {
// initially the widget was created as hidden
nsViewVisibility newVisibility =
aShow ? nsViewVisibility_kShow : nsViewVisibility_kHide;
nsViewVisibility currentVisibility;
view->GetVisibility(currentVisibility);
if (newVisibility != currentVisibility) {
// this only inits the 1st time
// XXX kipp says: this is yucky; init on first visibility seems lame
// XXX is this even called
nsIFormManager* formMan = ((nsInput*)mContent)->GetFormManager();
if (formMan) {
formMan->Init(PR_FALSE);
NS_RELEASE(formMan);
}
view->SetVisibility(newVisibility);
PostCreateWidget(aPresContext, view);
}
NS_IF_RELEASE(widget);
}
}
}
PRBool
nsInputFrame::BoundsAreSet()
{
if ((0 != mRect.width) || (0 != mRect.height)) {
return PR_TRUE;
} else {
return PR_FALSE;
}
}
PRBool
nsInputFrame::IsHidden()
{
nsInput* content = (nsInput *)mContent;
return content->IsHidden();
}
void
nsInputFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
// get the css size and let the frame use or override it
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
// subclasses should always override this method, but if not and no css, make it small
aDesiredLayoutSize.width = (styleSize.width > CSS_NOTSET) ? styleSize.width : 144;
aDesiredLayoutSize.height = (styleSize.height > CSS_NOTSET) ? styleSize.height : 144;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height = aDesiredLayoutSize.height;
}
void
nsInputFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredSize)
{
nsSize ignore;
GetDesiredSize(aPresContext, aReflowState, aDesiredSize, ignore);
}
NS_IMETHODIMP
nsInputFrame::DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus)
{
nsresult rv = nsInputFrameSuper::DidReflow(aPresContext, aStatus);
// The view is created hidden; once we have reflowed it and it has been
// positioned then we show it.
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
nsIView* view = nsnull;
GetView(view);
if (nsnull != view) {
view->SetVisibility(nsViewVisibility_kShow);
}
}
return rv;
}
NS_METHOD
nsInputFrame::Reflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
nsIView* view = nsnull;
GetView(view);
if (nsnull == view) {
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
// make sure the style context is set
if (nsnull == mStyleContext) {
GetStyleContext(&aPresContext, mStyleContext);
}
nsresult result =
nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID,
(void **)&view);
if (NS_OK != result) {
NS_ASSERTION(0, "Could not create view for button");
aStatus = NS_FRAME_NOT_COMPLETE;
return result;
}
nsIPresShell *presShell = aPresContext.GetShell(); // need to release
nsIViewManager *viewMan = presShell->GetViewManager(); // need to release
NS_RELEASE(presShell);
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize);
//nsRect boundBox(0, 0, mWidgetSize.width, mWidgetSize.height);
nsRect boundBox(0, 0, aDesiredSize.width, aDesiredSize.height);
nsIFrame* parWithView;
nsIView *parView;
GetParentWithView(parWithView);
parWithView->GetView(parView);
const nsIID& id = GetCID();
nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted
// initialize the view as hidden since we don't know the (x,y) until Paint
result = view->Init(viewMan, boundBox, parView, &id, initData,
nsnull, 0, nsnull,
1.0f, nsViewVisibility_kHide);
if (nsnull != initData) {
delete(initData);
}
if (NS_OK != result) {
NS_ASSERTION(0, "widget initialization failed");
aStatus = NS_FRAME_NOT_COMPLETE;
return NS_OK;
}
// set the content's widget, so it can get content modified by the widget
nsIWidget *widget;
result = GetWidget(view, &widget);
if (NS_OK == result) {
nsInput* content = (nsInput *)mContent; // change this cast to QueryInterface
content->SetWidget(widget);
NS_IF_RELEASE(widget);
} else {
NS_ASSERTION(0, "could not get widget");
}
viewMan->InsertChild(parView, view, 0);
SetView(view);
NS_IF_RELEASE(viewMan);
}
else {
GetDesiredSize(&aPresContext, aReflowState, aDesiredSize, mWidgetSize);
// If we are being reflowed and have a view, hide the view until
// we are told to paint (which is when our location will have
// stabilized).
// SetViewVisiblity(aPresContext, PR_FALSE);
}
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = aDesiredSize.width;
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
nsWidgetInitData*
nsInputFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
return nsnull;
}
void
nsInputFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
{
}
nsresult
nsInputFrame::GetWidget(nsIView* aView, nsIWidget** aWidget)
{
nsIWidget* widget;
aView->GetWidget(widget);
nsresult result;
if (nsnull == widget) {
aWidget = nsnull;
result = NS_ERROR_FAILURE;
} else {
const nsIID id = GetIID();
result = widget->QueryInterface(kIWidgetIID, (void**)aWidget);
if (NS_FAILED(result)) {
NS_ASSERTION(0, "The widget interface is invalid"); // need to print out more details of the widget
}
NS_RELEASE(widget);
}
return result;
}
const nsIID&
nsInputFrame::GetIID()
{
static NS_DEFINE_IID(kButtonIID, NS_IBUTTON_IID);
return kButtonIID;
}
const nsIID&
nsInputFrame::GetCID()
{
static NS_DEFINE_IID(kButtonCID, NS_BUTTON_CID);
return kButtonCID;
}
NS_METHOD nsInputFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
if (nsnull != mContent) {
mContent->HandleDOMEvent(aPresContext, (nsEvent*)aEvent, nsnull, DOM_EVENT_INIT, aEventStatus);
}
// make sure that the widget in the event is this
// XXX if there is no view, it could be an image button. Unfortunately,
// every image button will get every event.
nsIView* view;
GetView(view);
if (view) {
nsInput* content = (nsInput *)mContent;
if (content->GetWidget() != aEvent->widget) {
aEventStatus = nsEventStatus_eIgnore;
return NS_OK;
}
}
//printf(" %d %d %d %d (%d,%d) \n", this, aEvent->widget, aEvent->widgetSupports,
// aEvent->message, aEvent->point.x, aEvent->point.y);
switch (aEvent->message) {
case NS_MOUSE_ENTER:
mLastMouseState = eMouseEnter;
break;
case NS_MOUSE_LEFT_BUTTON_DOWN:
mLastMouseState =
(eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone;
break;
case NS_MOUSE_LEFT_BUTTON_UP:
if (eMouseDown == mLastMouseState) {
/*nsIView* view = GetView();
nsIWidget *widget = view->GetWindow();
widget->SetFocus();
NS_RELEASE(widget);
NS_RELEASE(view); */
float t2p = aPresContext.GetTwipsToPixels();
((nsInput*)mContent)->SetClickPoint(NSTwipsToIntPixels(aEvent->point.x, t2p),
NSTwipsToIntPixels(aEvent->point.y, t2p));
nsEventStatus mStatus = nsEventStatus_eIgnore;
nsMouseEvent mEvent;
mEvent.eventStructType = NS_MOUSE_EVENT;
mEvent.message = NS_MOUSE_LEFT_CLICK;
mContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
if (nsEventStatus_eConsumeNoDefault != mStatus) {
MouseClicked(&aPresContext);
//return PR_FALSE;
}
}
mLastMouseState = eMouseEnter;
break;
case NS_MOUSE_EXIT:
mLastMouseState = eMouseNone;
break;
case NS_KEY_DOWN:
if (NS_KEY_EVENT == aEvent->eventStructType) {
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
if (NS_VK_RETURN == keyEvent->keyCode) {
EnterPressed(aPresContext);
}
}
break;
}
aEventStatus = nsEventStatus_eConsumeDoDefault;
return NS_OK;
}
void nsInputFrame::GetStyleSize(nsIPresContext& aPresContext,
const nsReflowState& aReflowState,
nsSize& aSize)
{
PRIntn ss = nsCSSLayout::GetStyleSize(&aPresContext, aReflowState, aSize);
if (0 == (ss & NS_SIZE_HAS_WIDTH)) {
aSize.width = CSS_NOTSET;
}
if (0 == (ss & NS_SIZE_HAS_HEIGHT)) {
aSize.height = CSS_NOTSET;
}
}
nscoord
nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsInputFrame* aFrame,
const nsString& aString, nsSize& aSize)
{
nsFont font = aPresContext.GetDefaultFixedFont();
aFrame->GetFont(&aPresContext, font);
//printf("\n GetTextSize %s", aString.ToNewCString());
nsIDeviceContext* deviceContext = aPresContext.GetDeviceContext();
nsIFontCache* fontCache;
deviceContext->GetFontCache(fontCache);
nsIFontMetrics* fontMet;
fontCache->GetMetricsFor(font, fontMet);
fontMet->GetWidth(aString, aSize.width);
fontMet->GetHeight(aSize.height);
nscoord charWidth;
fontMet->GetWidth("W", charWidth);
NS_RELEASE(fontMet);
NS_RELEASE(fontCache);
NS_RELEASE(deviceContext);
return charWidth;
}
nscoord
nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsInputFrame* aFrame,
PRInt32 aNumChars, nsSize& aSize)
{
nsAutoString val;
char repChar = (kBackwardMode == aFrame->GetMode()) ? '%' : 'e';
for (int i = 0; i < aNumChars; i++) {
val += repChar;
}
return GetTextSize(aPresContext, aFrame, val, aSize);
}
PRInt32
nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame,
const nsSize& aCSSSize, nsInputDimensionSpec& aSpec,
nsSize& aBounds, PRBool& aWidthExplicit,
PRBool& aHeightExplicit, nscoord& aRowHeight)
{
nscoord charWidth = 0;
PRInt32 numRows = ATTR_NOTSET;
aWidthExplicit = PR_FALSE;
aHeightExplicit = PR_FALSE;
/* XXX For some reason on Win95 Paint doesn't initially get called */
/* for elements that are out of the view, so we weren't calling */
/* PostCreateWidget. I'm calling it here as a work-around */
nsIView* view = nsnull;
aFrame->GetView(view);
if (nsnull != view) {
if (PR_FALSE == aFrame->mDidInit) {
nsIFormManager* formMan = ((nsInput*)aFrame->mContent)->GetFormManager();
if (formMan) {
formMan->Init(PR_FALSE);
aFrame->PostCreateWidget(aPresContext, view);
aFrame->mDidInit = PR_TRUE;
NS_RELEASE(formMan);
}
}
}
aBounds.width = CSS_NOTSET;
aBounds.height = CSS_NOTSET;
nsSize textSize(0,0);
nsInput* content;
aFrame->GetContent((nsIContent*&) content);
nsAutoString valAttr;
nsresult valStatus = NS_CONTENT_ATTR_NOT_THERE;
if (nsnull != aSpec.mColValueAttr) {
valStatus = ((nsHTMLTagContent*)content)->GetAttribute(aSpec.mColValueAttr, valAttr);
}
nsHTMLValue colAttr;
nsresult colStatus = NS_CONTENT_ATTR_NOT_THERE;
if (nsnull != aSpec.mColSizeAttr) {
colStatus = content->GetAttribute(aSpec.mColSizeAttr, colAttr);
}
float p2t = aPresContext->GetPixelsToTwips();
// determine the width
nscoord adjSize;
if (NS_CONTENT_ATTR_HAS_VALUE == colStatus) { // col attr will provide width
if (aSpec.mColSizeAttrInPixels) {
adjSize = (colAttr.GetPixelValue() > 0) ? colAttr.GetPixelValue() : 15;
aBounds.width = NSIntPixelsToTwips(adjSize, p2t);
}
else {
PRInt32 col = ((colAttr.GetUnit() == eHTMLUnit_Pixel) ? colAttr.GetPixelValue() : colAttr.GetIntValue());
if (col <= 0) {
col = 1;
}
charWidth = GetTextSize(*aPresContext, aFrame, col, aBounds);
aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET
}
if (aSpec.mColSizeAttrInPixels) {
aWidthExplicit = PR_TRUE;
}
}
else {
if (CSS_NOTSET != aCSSSize.width) { // css provides width
aBounds.width = (aCSSSize.width > 0) ? aCSSSize.width : 1;
aWidthExplicit = PR_TRUE;
}
else {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) { // use width of initial value
charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds);
}
else if (aSpec.mColDefaultValue) { // use default value
charWidth = GetTextSize(*aPresContext, aFrame, *aSpec.mColDefaultValue, aBounds);
}
else if (aSpec.mColDefaultSizeInPixels) { // use default width in pixels
charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds);
aBounds.width = aSpec.mColDefaultSize;
}
else { // use default width in num characters
charWidth = GetTextSize(*aPresContext, aFrame, aSpec.mColDefaultSize, aBounds);
}
aRowHeight = aBounds.height; // XXX aBounds.height has CSS_NOTSET
}
}
// determine the height
nsHTMLValue rowAttr;
nsresult rowStatus = NS_CONTENT_ATTR_NOT_THERE;
if (nsnull != aSpec.mRowSizeAttr) {
rowStatus = content->GetAttribute(aSpec.mRowSizeAttr, rowAttr);
}
if (NS_CONTENT_ATTR_HAS_VALUE == rowStatus) { // row attr will provide height
PRInt32 rowAttrInt = ((rowAttr.GetUnit() == eHTMLUnit_Pixel) ? rowAttr.GetPixelValue() : rowAttr.GetIntValue());
adjSize = (rowAttrInt > 0) ? rowAttrInt : 1;
if (0 == charWidth) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
aBounds.height = textSize.height * adjSize;
aRowHeight = textSize.height;
numRows = adjSize;
}
else {
aBounds.height = aBounds.height * adjSize;
}
}
else if (CSS_NOTSET != aCSSSize.height) { // css provides height
aBounds.height = (aCSSSize.height > 0) ? aCSSSize.height : 1;
aHeightExplicit = PR_TRUE;
}
else { // use default height in num lines
if (0 == charWidth) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
aBounds.height = textSize.height * aSpec.mRowDefaultSize;
aRowHeight = textSize.height;
}
else {
aBounds.height = aBounds.height * aSpec.mRowDefaultSize;
}
}
if ((0 == charWidth) || (0 == textSize.width)) {
charWidth = GetTextSize(*aPresContext, aFrame, 1, textSize);
aRowHeight = textSize.height;
}
// add inside padding if necessary
if (!aWidthExplicit) {
aBounds.width += (2 * aFrame->GetHorizontalInsidePadding(p2t, aBounds.width, charWidth));
}
if (!aHeightExplicit) {
aBounds.height += (2 * aFrame->GetVerticalInsidePadding(p2t, textSize.height));
}
NS_RELEASE(content);
if (ATTR_NOTSET == numRows) {
numRows = aBounds.height / aRowHeight;
}
return numRows;
}
// this handles all of the input types rather than having them do it.
const void
nsInputFrame::GetFont(nsIPresContext* aPresContext, nsFont& aFont)
{
const nsStyleFont* styleFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
nsString type;
((nsInput*)mContent)->GetType(type);
// XXX shouldn't this be atom compares instead?
if ( type.EqualsIgnoreCase("text") ||
type.EqualsIgnoreCase("textarea") ||
type.EqualsIgnoreCase("password")) {
aFont = styleFont->mFixedFont;
} else if (type.EqualsIgnoreCase("button") ||
type.EqualsIgnoreCase("submit") ||
type.EqualsIgnoreCase("reset") ||
type.EqualsIgnoreCase("select")) {
if ((styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT) ||
(styleFont->mFlags & NS_STYLE_FONT_SIZE_EXPLICIT)) {
aFont = styleFont->mFixedFont;
aFont.weight = NS_FONT_WEIGHT_NORMAL; // always normal weight
aFont.size = styleFont->mFont.size; // normal font size
if (0 == (styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT)) {
aFont.name = "Arial"; // XXX windows specific font
}
} else {
// use arial, scaled down one HTML size
// italics, decoration & variant(?) get used
aFont = styleFont->mFont;
aFont.name = "Arial"; // XXX windows specific font
aFont.weight = NS_FONT_WEIGHT_NORMAL;
const nsFont& normal = aPresContext->GetDefaultFont();
PRInt32 scaler = aPresContext->GetFontScaler();
float scaleFactor = nsStyleUtil::GetScalingFactor(scaler);
PRInt32 fontIndex = nsStyleUtil::FindNextSmallerFontSize(aFont.size, (PRInt32)normal.size, scaleFactor);
aFont.size = nsStyleUtil::CalcFontPointSize(fontIndex, (PRInt32)normal.size, scaleFactor);
}
}
}

Просмотреть файл

@ -1,412 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInputRadio.h"
#include "nsInputFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsIRadioButton.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsHTMLAtoms.h"
#include "nsIFormManager.h"
#include "nsIView.h"
#include "nsIStyleContext.h"
#include "nsStyleUtil.h"
// prototypes
nsresult
NS_NewHTMLInputRadio(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager);
static NS_DEFINE_IID(kRadioIID, NS_IRADIOBUTTON_IID);
class nsInputRadioFrame : public nsInputFrame {
public:
nsInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual void MouseClicked(nsIPresContext* aPresContext);
protected:
virtual ~nsInputRadioFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewInputRadioFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputRadioFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputRadioFrame::nsInputRadioFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{
}
nsInputRadioFrame::~nsInputRadioFrame()
{
}
const nsIID&
nsInputRadioFrame::GetIID()
{
return kRadioIID;
}
const nsIID&
nsInputRadioFrame::GetCID()
{
static NS_DEFINE_IID(kRadioCID, NS_RADIOBUTTON_CID);
return kRadioCID;
}
void
nsInputRadioFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
float p2t = aPresContext->GetPixelsToTwips();
aDesiredWidgetSize.width = NSIntPixelsToTwips(12, p2t);
aDesiredWidgetSize.height = NSIntPixelsToTwips(12, p2t);
aDesiredLayoutSize.width = aDesiredWidgetSize.width;
aDesiredLayoutSize.height = aDesiredWidgetSize.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
}
void
nsInputRadioFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
{
nsInputRadio* content = (nsInputRadio *)mContent;
//PRInt32 checkedAttr;
//nsContentAttr result = ((nsInput *)content)->GetAttribute(nsHTMLAtoms::checked, checkedAttr);
//if ((result == eContentAttr_HasValue) && (PR_FALSE != checkedAttr)) {
nsIWidget* widget = nsnull;
nsIRadioButton* radio = nsnull;
nsresult result = GetWidget(aView, &widget);
if (NS_OK == result) {
result = widget->QueryInterface(GetIID(),(void**)&radio);
if (result == NS_OK)
{
radio->SetState(content->mForcedChecked);
const nsStyleColor* color =
nsStyleUtil::FindNonTransparentBackground(mStyleContext);
if (nsnull != color) {
widget->SetBackgroundColor(color->mBackgroundColor);
}
else {
widget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
}
NS_RELEASE(radio);
}
NS_RELEASE(widget);
}
}
// nsInputRadio
const nsString* nsInputRadio::kTYPE = new nsString("radio");
nsInputRadio::nsInputRadio(nsIAtom* aTag, nsIFormManager* aManager)
: nsInput(aTag, aManager)
{
mInitialChecked = PR_FALSE;
mForcedChecked = PR_FALSE;
}
nsInputRadio::~nsInputRadio()
{
}
static void
MapAttributesInto(nsIHTMLAttributes* aAttributes,
nsIStyleContext* aContext,
nsIPresContext* aPresContext)
{
float p2t = aPresContext->GetPixelsToTwips();
nscoord pad = NSIntPixelsToTwips(3, p2t);
// add left and right padding around the radio button via css
nsStyleSpacing* spacing = (nsStyleSpacing*) aContext->GetMutableStyleData(eStyleStruct_Spacing);
if (eStyleUnit_Null == spacing->mMargin.GetLeftUnit()) {
nsStyleCoord left(pad);
spacing->mMargin.SetLeft(left);
}
if (eStyleUnit_Null == spacing->mMargin.GetRightUnit()) {
nsStyleCoord right(NSIntPixelsToTwips(5, p2t));
spacing->mMargin.SetRight(right);
}
// add bottom padding if backward mode
// XXX why isn't this working?
nsCompatibility mode;
aPresContext->GetCompatibilityMode(mode);
if (eCompatibility_NavQuirks == mode) {
if (eStyleUnit_Null == spacing->mMargin.GetBottomUnit()) {
nsStyleCoord bottom(pad);
spacing->mMargin.SetBottom(bottom);
}
}
nsInput::MapAttributesInto(aAttributes, aContext, aPresContext);
}
NS_IMETHODIMP
nsInputRadio::GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const
{
aMapFunc = &MapAttributesInto;
return NS_OK;
}
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
void
nsInputRadioFrame::MouseClicked(nsIPresContext* aPresContext)
{
nsIRadioButton* radioWidget;
nsIView* view;
GetView(view);
if (NS_OK == GetWidget(view, (nsIWidget **)&radioWidget)) {
radioWidget->SetState(PR_TRUE);
NS_RELEASE(radioWidget);
nsInputRadio* radio;
GetContent((nsIContent *&) radio);
nsIFormControl* control;
nsresult status = radio->QueryInterface(kIFormControlIID, (void **)&control);
NS_ASSERTION(NS_OK == status, "nsInputRadio has no nsIFormControl interface");
if (NS_OK == status) {
nsIFormManager* formMan = radio->GetFormManager();
if (formMan) {
formMan->OnRadioChecked(*control);
NS_RELEASE(formMan);
}
NS_RELEASE(radio);
}
}
}
PRBool
nsInputRadio::GetChecked(PRBool aGetInitialValue) const
{
if (aGetInitialValue) {
return mInitialChecked;
}
else {
if (mWidget) {
PRBool state = PR_FALSE;
nsIRadioButton* radio = nsnull;
nsresult result = mWidget->QueryInterface(kRadioIID,(void**)&radio);
if (result == NS_OK)
{
radio->GetState(state);
NS_IF_RELEASE(radio);
}
return state;
}
else {
return mForcedChecked;
}
}
}
void
nsInputRadio::SetChecked(PRBool aValue, PRBool aSetInitialValue)
{
mForcedChecked = aValue;
if (aSetInitialValue) {
mInitialChecked = aValue;
}
//NS_ASSERTION(mWidget, "no widget for this nsInputRadio");
if (mWidget) {
((nsIRadioButton *)mWidget)->SetState(aValue);
}
}
void nsInputRadio::GetType(nsString& aResult) const
{
aResult = "radio";
}
NS_IMETHODIMP
nsInputRadio::SetAttribute(nsIAtom* aAttribute,
const nsString& aValue,
PRBool aNotify)
{
if (aAttribute == nsHTMLAtoms::checked) {
mInitialChecked = PR_TRUE;
mForcedChecked = PR_TRUE;
}
return nsInputRadioSuper::SetAttribute(aAttribute, aValue, aNotify);
}
NS_IMETHODIMP
nsInputRadio::GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const
{
aResult.Reset();
if (aAttribute == nsHTMLAtoms::checked) {
return GetCacheAttribute(mInitialChecked, aResult, eHTMLUnit_Empty);
}
else {
return nsInputRadioSuper::GetAttribute(aAttribute, aResult);
}
}
PRBool
nsInputRadio::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if ((aMaxNumValues <= 0) || (nsnull == mName)) {
return PR_FALSE;
}
nsIWidget* widget = GetWidget();
nsIRadioButton* radio = nsnull;
PRBool state = PR_FALSE;
if (widget != nsnull)
{
widget->QueryInterface(kRadioIID,(void**)&radio);
radio->GetState(state);
NS_IF_RELEASE(radio);
}
if(PR_TRUE != state) {
return PR_FALSE;
}
if (nsnull == mValue) {
aValues[0] = "on";
} else {
aValues[0] = *mValue;
}
aNames[0] = *mName;
aNumValues = 1;
return PR_TRUE;
}
void
nsInputRadio::Reset()
{
nsIWidget* widget = GetWidget();
nsIRadioButton* radio = nsnull;
if (widget != nsnull && NS_OK == widget->QueryInterface(kRadioIID,(void**)&radio))
{
radio->SetState(mInitialChecked);
NS_RELEASE(radio);
}
}
nsresult
NS_NewHTMLInputRadio(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputRadio(aTag, aManager);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
// CLASS nsInputRadioGroup
nsInputRadioGroup::nsInputRadioGroup(nsString& aName)
:mName(aName), mCheckedRadio(nsnull)
{
}
nsInputRadioGroup::~nsInputRadioGroup()
{
mCheckedRadio = nsnull;
}
PRInt32
nsInputRadioGroup::GetRadioCount() const
{
return mRadios.Count();
}
nsIFormControl*
nsInputRadioGroup::GetRadioAt(PRInt32 aIndex) const
{
return (nsIFormControl*) mRadios.ElementAt(aIndex);
}
PRBool
nsInputRadioGroup::AddRadio(nsIFormControl* aRadio)
{
return mRadios.AppendElement(aRadio);
}
PRBool
nsInputRadioGroup::RemoveRadio(nsIFormControl* aRadio)
{
return mRadios.RemoveElement(aRadio);
}
nsIFormControl*
nsInputRadioGroup::GetCheckedRadio()
{
return mCheckedRadio;
}
void
nsInputRadioGroup::SetCheckedRadio(nsIFormControl* aRadio)
{
mCheckedRadio = aRadio;
}
void
nsInputRadioGroup::GetName(nsString& aNameResult) const
{
aNameResult = mName;
}

Просмотреть файл

@ -1,89 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsInputRadio_h___
#define nsInputRadio_h___
// this class defintion will be moved into nsInputRadio.cpp
#include "nsInput.h"
#include "nsVoidArray.h"
class nsIAtom;
class nsString;
class nsInputRadio : public nsInput
{
public:
typedef nsInput nsInputRadioSuper;
nsInputRadio (nsIAtom* aTag, nsIFormManager* aManager);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const;
static const nsString* kTYPE;
virtual PRBool GetChecked(PRBool aGetInitialValue) const;
virtual void SetChecked(PRBool aValue, PRBool aSetInitialValue);
virtual PRInt32 GetMaxNumValues() { return 1; }
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
NS_IMETHOD GetAttributeMappingFunction(nsMapAttributesFunc& aMapFunc) const;
virtual void Reset();
protected:
virtual ~nsInputRadio();
virtual void GetType(nsString& aResult) const;
PRBool mInitialChecked;
PRBool mForcedChecked;
friend class nsInputRadioFrame;
};
class nsInputRadioGroup
{
public:
nsInputRadioGroup(nsString& aName);
virtual ~nsInputRadioGroup();
PRBool AddRadio(nsIFormControl* aRadio);
PRInt32 GetRadioCount() const;
nsIFormControl* GetRadioAt(PRInt32 aIndex) const;
PRBool RemoveRadio(nsIFormControl* aRadio);
nsIFormControl* GetCheckedRadio();
void SetCheckedRadio(nsIFormControl* aRadio);
void GetName(nsString& aNameResult) const;
protected:
nsString mName;
nsVoidArray mRadios;
nsIFormControl* mCheckedRadio;
};
#endif

Просмотреть файл

@ -1,554 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsInputText.h"
#include "nsInputFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"
#include "nsHTMLAtoms.h"
#include "nsHTMLForms.h"
#include "nsIStyleContext.h"
#include "nsFont.h"
#include "nsDOMEvent.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
class nsInputTextFrame : public nsInputFrame {
public:
nsInputTextFrame(nsIContent* aContent,
nsIFrame* aParentFrame);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual void EnterPressed(nsIPresContext& aPresContext) ;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
protected:
virtual ~nsInputTextFrame();
nsInputTextType GetTextType();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
nsresult
NS_NewInputTextFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsInputTextFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsInputTextFrame::nsInputTextFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{
}
nsInputTextFrame::~nsInputTextFrame()
{
}
nscoord nsInputTextFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(4, aPixToTwip);
}
nscoord nsInputTextFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
// for a text area aInnerHeight is the height of one line
nscoord nsInputTextFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
#ifdef XP_PC
nsAutoString type;
((nsInput*)mContent)->GetType(type);
if (type.EqualsIgnoreCase("textarea")) {
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.40f);
} else {
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.25f);
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(10, aPixToTwip); // XXX this is probably wrong
#endif
}
nscoord nsInputTextFrame::GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
#ifdef XP_PC
nscoord padding;
nsAutoString type;
((nsInput*)mContent)->GetType(type);
if (type.EqualsIgnoreCase("textarea")) {
padding = (nscoord)(40 * aCharWidth / 100);
} else {
padding = (nscoord)(55 * aCharWidth / 100);
}
nscoord min = NSIntPixelsToTwips(3, aPixToTwip);
if (padding > min) {
return padding;
} else {
return min;
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(6, aPixToTwip); // XXX this is probably wrong
#endif
}
static NS_DEFINE_IID(kTextIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kTextAreaIID, NS_ITEXTAREAWIDGET_IID);
const nsIID&
nsInputTextFrame::GetIID()
{
if (kInputText_Area == GetTextType()) {
return kTextAreaIID;
}
else {
return kTextIID;
}
}
const nsIID&
nsInputTextFrame::GetCID()
{
static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID);
static NS_DEFINE_IID(kTextAreaCID, NS_TEXTAREA_CID);
if (kInputText_Area == GetTextType()) {
return kTextAreaCID;
}
else {
return kTextCID;
}
}
nsInputTextType
nsInputTextFrame::GetTextType()
{
nsInputText* content;
GetContent((nsIContent *&) content);
nsInputTextType type = content->GetTextType();
NS_RELEASE(content);
return type;
}
void
nsInputTextFrame::EnterPressed(nsIPresContext& aPresContext)
{
nsInputText* text = (nsInputText *)mContent;
nsIFormManager* formMan = text->GetFormManager();
if (nsnull != formMan) {
nsInputTextType type = text->GetTextType();
// a form with one text area causes a submit when the enter key is pressed
// XXX this logic should be in the form manager, but then it needs to be passed
// enough to trigger the dom event.
if ((kInputText_Text == type) && text->GetCanSubmit()) {
nsEventStatus mStatus = nsEventStatus_eIgnore;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
nsIFormControl* control;
mContent->QueryInterface(kIFormControlIID, (void**)&control);
formMan->OnSubmit(&aPresContext, this, control);
NS_IF_RELEASE(control);
}
NS_RELEASE(formMan);
}
}
void
nsInputTextFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
nsInputTextType textType = GetTextType();
// get the css size and let the frame use or override it
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
nsSize size;
PRBool widthExplicit, heightExplicit;
PRInt32 ignore;
if ((kInputText_Text == textType) || (kInputText_Password == textType) ||
(kInputText_FileText == textType)) {
nsHTMLValue sizeAttr;
PRInt32 width = 21;
if (NS_CONTENT_ATTR_HAS_VALUE == ((nsInput*)mContent)->GetAttribute(nsHTMLAtoms::size, sizeAttr)) {
width = (sizeAttr.GetUnit() == eHTMLUnit_Pixel) ? sizeAttr.GetPixelValue() : sizeAttr.GetIntValue();
if (kBackwardMode == GetMode()) {
width += 1;
}
}
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
nsnull, width, PR_FALSE, nsnull, 1);
// nsInputDimensionSpec textSpec(nsHTMLAtoms::size, PR_FALSE, nsnull,
// nsnull, 21, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, textSpec, size,
widthExplicit, heightExplicit, ignore);
}
else {
nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, nsnull, 20,
PR_FALSE, nsHTMLAtoms::rows, 1);
CalculateSize(aPresContext, this, styleSize, areaSpec, size,
widthExplicit, heightExplicit, ignore);
}
if (kInputText_Area == textType) {
float p2t = aPresContext->GetPixelsToTwips();
nscoord scrollbarWidth = GetScrollbarWidth(p2t);
if (!heightExplicit) {
size.height += scrollbarWidth;
}
if (!widthExplicit) {
size.width += scrollbarWidth;
}
}
aDesiredLayoutSize.width = size.width;
aDesiredLayoutSize.height = size.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height = aDesiredLayoutSize.height;
}
nsWidgetInitData*
nsInputTextFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
nsTextWidgetInitData* data = nsnull;
nsInputText* content;
GetContent((nsIContent *&) content);
if (kInputText_Password == content->GetTextType()) {
data = new nsTextWidgetInitData();
data->clipChildren = PR_TRUE;
data->mIsPassword = PR_TRUE;
}
NS_RELEASE(content);
return data;
}
void
nsInputTextFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
{
nsIWidget* widget = nsnull;
if (NS_OK == GetWidget(aView, &widget)) {
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
// This is replicated code for both text interfaces -- this should be factored
if (widget != nsnull && NS_OK == widget->QueryInterface(kTextIID,(void**)&text))
{
const nsStyleFont* fontStyle = (const nsStyleFont*)(mStyleContext->GetStyleData(eStyleStruct_Font));
widget->SetFont(fontStyle->mFixedFont);
nsInputText* content;
GetContent((nsIContent *&) content);
nsAutoString valAttr;
nsresult valStatus = ((nsHTMLTagContent *)content)->GetAttribute(nsHTMLAtoms::value, valAttr);
PRUint32 size;
text->SetText(valAttr,size);
PRInt32 maxLength = content->GetMaxLength();
if (ATTR_NOTSET != maxLength) {
text->SetMaxTextLength(maxLength);
}
widget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
NS_RELEASE(content);
NS_RELEASE(text);
}
else if (widget != nsnull && NS_OK == widget->QueryInterface(kTextAreaIID,(void**)&textArea))
{
const nsStyleFont* fontStyle = (const nsStyleFont*)(mStyleContext->GetStyleData(eStyleStruct_Font));
widget->SetFont(fontStyle->mFixedFont);
nsInputText* content;
GetContent((nsIContent *&) content);
nsAutoString valAttr;
nsresult valStatus = ((nsHTMLTagContent *)content)->GetAttribute(nsHTMLAtoms::value, valAttr);
PRUint32 size;
textArea->SetText(valAttr,size);
PRInt32 maxLength = content->GetMaxLength();
if (ATTR_NOTSET != maxLength) {
textArea->SetMaxTextLength(maxLength);
}
widget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
NS_RELEASE(content);
NS_RELEASE(textArea);
}
}
}
//----------------------------------------------------------------------
// nsInputText
nsInputText::nsInputText(nsIAtom* aTag, nsIFormManager* aManager, nsInputTextType aType)
: nsInput(aTag, aManager), mType(aType)
{
mMaxLength = ATTR_NOTSET;
mNumRows = ATTR_NOTSET;
mNumCols = ATTR_NOTSET;
}
nsInputText::~nsInputText()
{
}
nsInputTextType
nsInputText::GetTextType() const
{
return mType;
}
PRInt32
nsInputText::GetMaxNumValues()
{
return 1;
}
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
PRBool
nsInputText::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if ((aMaxNumValues <= 0) || (nsnull == mName)) {
return PR_FALSE;
}
nsIWidget* widget = GetWidget();
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
if (widget != nsnull && NS_OK == widget->QueryInterface(kITextWidgetIID,(void**)&text))
{
nsString value;
PRUint32 size;
text->GetText(aValues[0],0,size); // the last parm is not used
aNames[0] = *mName;
aNumValues = 1;
NS_RELEASE(text);
return PR_TRUE;
}
else if (widget != nsnull && NS_OK == widget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea))
{
nsString value;
PRUint32 size;
textArea->GetText(aValues[0],0,size); // the last parm is not used
aNames[0] = *mName;
aNumValues = 1;
NS_RELEASE(textArea);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsInputText::Reset()
{
nsIWidget* widget = GetWidget();
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
if (widget != nsnull && NS_OK == widget->QueryInterface(kTextIID,(void**)&text))
{
PRUint32 size;
if (nsnull == mValue) {
text->SetText("",size);
} else {
text->SetText(*mValue,size);
}
NS_RELEASE(text);
}
else if (widget != nsnull && NS_OK == widget->QueryInterface(kTextAreaIID,(void**)&textArea))
{
PRUint32 size;
if (nsnull == mValue) {
textArea->SetText("",size);
} else {
textArea->SetText(*mValue,size);
}
NS_RELEASE(textArea);
}
}
void nsInputText::GetType(nsString& aResult) const
{
if (kInputText_Text == mType) {
aResult = "text";
}
else if (kInputText_Password == mType) {
aResult = "password";
}
else if (kInputText_Area == mType) {
aResult = "textarea";
}
else if (kInputText_FileText == mType) {
aResult = "filetext";
}
}
NS_IMETHODIMP
nsInputText::SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify)
{
if (aAttribute == nsHTMLAtoms::maxlength) {
CacheAttribute(aValue, ATTR_NOTSET, mMaxLength);
}
else if ((aAttribute == nsHTMLAtoms::rows) && (kInputText_Area == mType)) {
CacheAttribute(aValue, ATTR_NOTSET, mNumRows);
}
else if ((aAttribute == nsHTMLAtoms::cols) && (kInputText_Area == mType)) {
CacheAttribute(aValue, ATTR_NOTSET, mNumCols);
}
return nsInputTextSuper::SetAttribute(aAttribute, aValue, aNotify);
}
NS_IMETHODIMP
nsInputText::GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const
{
if (aAttribute == nsHTMLAtoms::maxlength) {
return GetCacheAttribute(mMaxLength, aResult, eHTMLUnit_Integer);
}
else if ((aAttribute == nsHTMLAtoms::rows) && (kInputText_Area == mType)) {
return GetCacheAttribute(mNumRows, aResult, eHTMLUnit_Integer);
}
else if ((aAttribute == nsHTMLAtoms::cols) && (kInputText_Area == mType)) {
return GetCacheAttribute(mNumCols, aResult, eHTMLUnit_Integer);
}
else {
return nsInputTextSuper::GetAttribute(aAttribute, aResult);
}
}
nsresult
NS_NewHTMLInputText(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputText_Text);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
nsresult
NS_NewHTMLInputPassword(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputText_Password);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
nsresult
NS_NewHTMLInputFileText(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputText_FileText);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
nsresult
NS_NewHTMLTextArea(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aManager)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsInputText(aTag, aManager, kInputText_Area);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}

Просмотреть файл

@ -1,79 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsInputText_h___
#define nsInputText_h___
#include "nsInput.h"
#include "nsString.h"
class nsIAtom;
class nsString;
class nsView;
enum nsInputTextType {
kInputText_Text,
kInputText_FileText,
kInputText_Password,
kInputText_Area
};
// this class definition will move to nsInputText.cpp
class nsInputText : public nsInput {
public:
typedef nsInput nsInputTextSuper;
nsInputText (nsIAtom* aTag, nsIFormManager* aManager, nsInputTextType aType);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const;
virtual PRInt32 GetMaxNumValues();
nsInputTextType GetTextType() const;
PRInt32 GetMaxLength() const { return mMaxLength; }
// From nsIDOMHTMLInputElement interface
NS_IMETHOD GetMaxLength(PRInt32* aMaxLength)
{ *aMaxLength = mMaxLength; return NS_OK; }
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
protected:
virtual ~nsInputText();
virtual void GetType(nsString& aResult) const;
nsInputTextType mType;
PRInt32 mMaxLength; // text, password only
PRInt32 mNumRows; // textarea only
PRInt32 mNumCols; // textarea only
};
#endif

Просмотреть файл

@ -0,0 +1,281 @@
/* -*- 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 "nsRadioControlFrame.h"
#include "nsFormControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsIRadioButton.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsHTMLAtoms.h"
#include "nsIFormControl.h"
#include "nsIFormManager.h"
#include "nsIView.h"
#include "nsIStyleContext.h"
#include "nsStyleUtil.h"
#include "nsFormFrame.h"
static NS_DEFINE_IID(kIRadioIID, NS_IRADIOBUTTON_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
nsresult
NS_NewRadioControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsRadioControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsRadioControlFrame::nsRadioControlFrame(nsIContent* aContent, nsIFrame* aParentFrame)
: nsFormControlFrame(aContent, aParentFrame)
{
mInitialChecked = nsnull;
mForcedChecked = PR_FALSE;
}
nsRadioControlFrame::~nsRadioControlFrame()
{
if (mInitialChecked) {
delete mInitialChecked;
}
}
const nsIID&
nsRadioControlFrame::GetIID()
{
return kIRadioIID;
}
const nsIID&
nsRadioControlFrame::GetCID()
{
static NS_DEFINE_IID(kRadioCID, NS_RADIOBUTTON_CID);
return kRadioCID;
}
void
nsRadioControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
float p2t = aPresContext->GetPixelsToTwips();
aDesiredWidgetSize.width = NSIntPixelsToTwips(12, p2t);
aDesiredWidgetSize.height = NSIntPixelsToTwips(12, p2t);
aDesiredLayoutSize.width = aDesiredWidgetSize.width;
aDesiredLayoutSize.height = aDesiredWidgetSize.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
}
void
nsRadioControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
{
nsIRadioButton* radio = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(GetIID(),(void**)&radio))) {
radio->SetState(mForcedChecked);
const nsStyleColor* color =
nsStyleUtil::FindNonTransparentBackground(mStyleContext);
if (nsnull != color) {
mWidget->SetBackgroundColor(color->mBackgroundColor);
} else {
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
}
NS_RELEASE(radio);
}
}
void
nsRadioControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
nsIRadioButton* radioWidget;
if (mWidget && (NS_OK == mWidget->QueryInterface(kIRadioIID, (void**)&radioWidget))) {
radioWidget->SetState(PR_TRUE);
NS_RELEASE(radioWidget);
if (mFormFrame) {
mFormFrame->OnRadioChecked(*this);
}
}
}
PRBool
nsRadioControlFrame::GetChecked(PRBool aGetInitialValue)
{
if (aGetInitialValue) {
if (!mInitialChecked && mContent) {
mInitialChecked = new PRBool(PR_FALSE);
nsIHTMLContent* iContent = nsnull;
nsresult result = mContent->QueryInterface(kIHTMLContentIID, (void**)&iContent);
if ((NS_OK == result) && iContent) {
nsHTMLValue value;
result = iContent->GetAttribute(nsHTMLAtoms::checked, value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
*mInitialChecked = PR_TRUE;
mForcedChecked = PR_TRUE;
}
NS_RELEASE(iContent);
}
}
return *mInitialChecked;
}
PRBool result = PR_FALSE;
nsIRadioButton* radio = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(kIRadioIID,(void**)&radio))) {
radio->GetState(result);
NS_RELEASE(radio);
} else {
result = mForcedChecked;
}
return result;
}
void
nsRadioControlFrame::SetChecked(PRBool aValue, PRBool aSetInitialValue)
{
mForcedChecked = aValue;
if (aSetInitialValue) {
if (!mInitialChecked) {
mInitialChecked = new PRBool(aValue);
}
*mInitialChecked = aValue;
}
nsIRadioButton* radio = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(kIRadioIID,(void**)&radio))) {
radio->SetState(aValue);
NS_RELEASE(radio);
}
}
PRBool
nsRadioControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_HAS_VALUE != result)) {
return PR_FALSE;
}
PRBool state = PR_FALSE;
nsIRadioButton* radio = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(kIRadioIID,(void**)&radio))) {
radio->GetState(state);
NS_RELEASE(radio);
}
if(PR_TRUE != state) {
return PR_FALSE;
}
nsAutoString value;
result = GetValue(&value);
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
aValues[0] = value;
} else {
aValues[0] = "on";
}
aNames[0] = name;
aNumValues = 1;
return PR_TRUE;
}
void
nsRadioControlFrame::Reset()
{
nsIRadioButton* radio = nsnull;
if (mWidget && (NS_OK == mWidget->QueryInterface(kIRadioIID,(void**)&radio))) {
PRBool state = (nsnull == mInitialChecked) ? PR_FALSE : *mInitialChecked;
radio->SetState(state);
NS_RELEASE(radio);
}
}
// CLASS nsRadioControlGroup
nsRadioControlGroup::nsRadioControlGroup(nsString& aName)
:mName(aName), mCheckedRadio(nsnull)
{
}
nsRadioControlGroup::~nsRadioControlGroup()
{
mCheckedRadio = nsnull;
}
PRInt32
nsRadioControlGroup::GetRadioCount() const
{
return mRadios.Count();
}
nsRadioControlFrame*
nsRadioControlGroup::GetRadioAt(PRInt32 aIndex) const
{
return (nsRadioControlFrame*) mRadios.ElementAt(aIndex);
}
PRBool
nsRadioControlGroup::AddRadio(nsRadioControlFrame* aRadio)
{
return mRadios.AppendElement(aRadio);
}
PRBool
nsRadioControlGroup::RemoveRadio(nsRadioControlFrame* aRadio)
{
return mRadios.RemoveElement(aRadio);
}
nsRadioControlFrame*
nsRadioControlGroup::GetCheckedRadio()
{
return mCheckedRadio;
}
void
nsRadioControlGroup::SetCheckedRadio(nsRadioControlFrame* aRadio)
{
mCheckedRadio = aRadio;
}
void
nsRadioControlGroup::GetName(nsString& aNameResult) const
{
aNameResult = mName;
}

Просмотреть файл

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsRadioControlFrame_h___
#define nsRadioControlFrame_h___
#include "nsFormControlFrame.h"
#include "nsVoidArray.h"
#include "nsString.h"
class nsIAtom;
// nsRadioControlFrame
class nsRadioControlFrame : public nsFormControlFrame
{
public:
nsRadioControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual PRBool GetChecked(PRBool aGetInitialValue);
virtual void SetChecked(PRBool aValue, PRBool aSetInitialValue);
virtual PRInt32 GetMaxNumValues() { return 1; }
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void MouseClicked(nsIPresContext* aPresContext);
virtual void Reset();
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
protected:
virtual ~nsRadioControlFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
PRBool *mInitialChecked;
PRBool mForcedChecked;
};
// nsRadioControlGroup
class nsRadioControlGroup
{
public:
nsRadioControlGroup(nsString& aName);
virtual ~nsRadioControlGroup();
PRBool AddRadio(nsRadioControlFrame* aRadio);
PRInt32 GetRadioCount() const;
nsRadioControlFrame* GetRadioAt(PRInt32 aIndex) const;
PRBool RemoveRadio(nsRadioControlFrame* aRadio);
nsRadioControlFrame* GetCheckedRadio();
void SetCheckedRadio(nsRadioControlFrame* aRadio);
void GetName(nsString& aNameResult) const;
protected:
nsString mName;
nsVoidArray mRadios;
nsRadioControlFrame* mCheckedRadio;
};
#endif

Просмотреть файл

@ -1,754 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// YY need to pass isMultiple before create called
#include "nsInputFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsIRadioButton.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsHTMLAtoms.h"
#include "nsIFormManager.h"
#include "nsIView.h"
#include "nsIListWidget.h"
#include "nsIComboBox.h"
#include "nsIListBox.h"
#include "nsInput.h"
#include "nsHTMLForms.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsStyleUtil.h"
#include "nsFont.h"
#define NS_IOPTION_IID \
{ 0xfa6a8b11, 0x2af2, 0x11d2, \
{ 0x80, 0x3a, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } }
static NS_DEFINE_IID(kListWidgetIID, NS_ILISTWIDGET_IID);
static NS_DEFINE_IID(kComboBoxIID, NS_ICOMBOBOX_IID);
static NS_DEFINE_IID(kListBoxIID, NS_ILISTBOX_IID);
static NS_DEFINE_IID(kOptionIID, NS_IOPTION_IID);
class nsOption;
class nsSelectFrame : public nsInputFrame {
public:
nsSelectFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
protected:
virtual ~nsSelectFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
class nsSelect : public nsInput
{
public:
typedef nsInput nsSelectSuper;
nsSelect (nsIAtom* aTag, nsIFormManager* aFormMan);
nsOption* GetNthOption(PRInt32 aIndex);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
PRBool IsMultiple() { return mMultiple; }
PRBool GetMultiple() const { return mMultiple; }
virtual void Reset();
PRBool mIsComboBox;
protected:
virtual ~nsSelect();
virtual void GetType(nsString& aResult) const;
PRBool mMultiple;
};
class nsOption : public nsInput
{
public:
typedef nsInput nsOptionSuper;
nsOption (nsIAtom* aTag);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_IMETHOD SetAttribute(nsIAtom* aAttribute, const nsString& aValue,
PRBool aNotify);
NS_IMETHOD GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual PRBool GetContent(nsString& aString) const;
virtual void SetContent(const nsString& aValue);
void CompressContent();
protected:
virtual ~nsOption();
virtual void GetType(nsString& aResult) const;
PRBool mSelected;
nsString* mContent;
};
nsresult
NS_NewHTMLSelectFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsSelectFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsSelectFrame::nsSelectFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsInputFrame(aContent, aParentFrame)
{
}
nsSelectFrame::~nsSelectFrame()
{
}
nscoord nsSelectFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(1, aPixToTwip);
}
nscoord nsSelectFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
nscoord nsSelectFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
#ifdef XP_PC
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.15f);
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(1, aPixToTwip); // XXX this is probably wrong
#endif
}
PRInt32 nsSelectFrame::GetHorizontalInsidePadding(float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
#ifdef XP_PC
nscoord padding = (nscoord)NSToIntRound(float(aCharWidth) * 0.40f);
nscoord min = NSIntPixelsToTwips(3, aPixToTwip);
if (padding > min) {
return padding;
} else {
return min;
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(7, aPixToTwip); // XXX this is probably wrong
#endif
}
const nsIID&
nsSelectFrame::GetIID()
{
nsSelect* content = (nsSelect *)mContent;
if (content->mIsComboBox) {
return kComboBoxIID;
}
else {
return kListBoxIID;
}
}
const nsIID&
nsSelectFrame::GetCID()
{
static NS_DEFINE_IID(kComboCID, NS_COMBOBOX_CID);
static NS_DEFINE_IID(kListCID, NS_LISTBOX_CID);
nsSelect* content = (nsSelect *)mContent;
if (content->mIsComboBox) {
return kComboCID;
}
else {
return kListCID;
}
}
void
nsSelectFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
nsSelect* select;
GetContent((nsIContent *&)select);
// get the css size
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
// get the size of the longest option child
PRInt32 maxWidth = 1;
PRInt32 numChildren;
select->ChildCount(numChildren);
for (int childX = 0; childX < numChildren; childX++) {
nsIContent* child;
select->ChildAt(childX, child);
nsOption* option;
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
if (NS_OK == result) {
option->CompressContent();
nsString text;
if (PR_FALSE == option->GetContent(text)) {
continue;
}
nsSize textSize;
// use the style for the select rather that the option, since widgets don't support it
nsInputFrame::GetTextSize(*aPresContext, this, text, textSize);
if (textSize.width > maxWidth) {
maxWidth = textSize.width;
}
NS_RELEASE(option);
}
NS_RELEASE(child);
}
PRInt32 rowHeight = 0;
nsSize calcSize, charSize;
PRBool widthExplicit, heightExplicit;
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull,
maxWidth, PR_TRUE, nsHTMLAtoms::size, 1);
PRInt32 numRows = CalculateSize(aPresContext, this, styleSize, textSpec,
calcSize, widthExplicit, heightExplicit, rowHeight);
// here it is determined whether we are a combo box
PRInt32 sizeAttr = select->GetSize();
if (!select->GetMultiple() && ((1 >= sizeAttr) || ((ATTR_NOTSET == sizeAttr) && (1 >= numRows)))) {
select->mIsComboBox = PR_TRUE;
}
aDesiredLayoutSize.width = calcSize.width;
// account for vertical scrollbar, if present
if (!widthExplicit && ((numRows < numChildren) || select->mIsComboBox)) {
float p2t = aPresContext->GetPixelsToTwips();
aDesiredLayoutSize.width += GetScrollbarWidth(p2t);
}
// XXX put this in widget library, combo boxes are fixed height (visible part)
aDesiredLayoutSize.height = (select->mIsComboBox) ? 350 : calcSize.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height = aDesiredLayoutSize.height;
if (select->mIsComboBox) { // add in pull down size
aDesiredWidgetSize.height += (rowHeight * (numChildren > 20 ? 20 : numChildren)) + 100;
}
NS_RELEASE(select);
}
nsWidgetInitData*
nsSelectFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
nsSelect* select = (nsSelect *)mContent;
if (select->mIsComboBox) {
nsComboBoxInitData* initData = new nsComboBoxInitData();
initData->clipChildren = PR_TRUE;
float twipToPix = aPresContext.GetTwipsToPixels();
initData->mDropDownHeight = NSTwipsToIntPixels(mWidgetSize.height, twipToPix);
return initData;
}
else {
nsListBoxInitData* initData = nsnull;
nsSelect* content;
GetContent((nsIContent *&) content);
if (content->IsMultiple()) {
initData = new nsListBoxInitData();
initData->clipChildren = PR_TRUE;
initData->mMultiSelect = PR_TRUE;
}
NS_RELEASE(content);
return initData;
}
}
void
nsSelectFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView)
{
nsSelect* select;
GetContent((nsIContent *&)select);
nsIView* view;
GetView(view);
nsIWidget* widget;
view->GetWidget(widget);
nsIListWidget* list;
if ((nsnull == widget) || NS_FAILED(widget->QueryInterface(kListWidgetIID, (void **) &list))) {
NS_ASSERTION(PR_FALSE, "invalid widget");
return;
}
widget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
const nsStyleFont* styleFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
if ((styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT) ||
(styleFont->mFlags & NS_STYLE_FONT_SIZE_EXPLICIT)) {
nsFont widgetFont(styleFont->mFixedFont);
widgetFont.weight = NS_FONT_WEIGHT_NORMAL; // always normal weight
widgetFont.size = styleFont->mFont.size; // normal font size
if (0 == (styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT)) {
widgetFont.name = "Arial"; // XXX windows specific font
}
widget->SetFont(widgetFont);
}
else {
// use arial, scaled down one HTML size
// italics, decoration & variant(?) get used
nsFont widgetFont(styleFont->mFont);
widgetFont.name = "Arial"; // XXX windows specific font
widgetFont.weight = NS_FONT_WEIGHT_NORMAL;
const nsFont& normal = aPresContext->GetDefaultFont();
PRInt32 scaler = aPresContext->GetFontScaler();
float scaleFactor = nsStyleUtil::GetScalingFactor(scaler);
PRInt32 fontIndex = nsStyleUtil::FindNextSmallerFontSize(widgetFont.size, (PRInt32)normal.size, scaleFactor);
widgetFont.size = nsStyleUtil::CalcFontPointSize(fontIndex, (PRInt32)normal.size, scaleFactor);
widget->SetFont(widgetFont);
}
PRInt32 numChildren;
select->ChildCount(numChildren);
int optionX = -1;
for (int childX = 0; childX < numChildren; childX++) {
nsIContent* child;
select->ChildAt(childX, child);
nsOption* option;
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
if (NS_OK == result) {
optionX++;
nsString text;
if (PR_TRUE != option->GetContent(text)) {
text = " ";
}
list->AddItemAt(text, optionX);
NS_RELEASE(option);
}
NS_RELEASE(child);
}
NS_RELEASE(list);
NS_RELEASE(widget);
select->Reset(); // initializes selections
}
// nsSelect
nsSelect::nsSelect(nsIAtom* aTag, nsIFormManager* aFormMan)
: nsInput(aTag, aFormMan), mIsComboBox(PR_FALSE)
{
mMultiple = PR_FALSE;
}
nsSelect::~nsSelect()
{
}
void nsSelect::GetType(nsString& aResult) const
{
aResult = "select";
}
NS_IMETHODIMP
nsSelect::SetAttribute(nsIAtom* aAttribute,
const nsString& aValue,
PRBool aNotify)
{
if (aAttribute == nsHTMLAtoms::multiple) {
mMultiple = PR_TRUE;
}
return nsSelectSuper::SetAttribute(aAttribute, aValue, aNotify);
}
NS_IMETHODIMP
nsSelect::GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const
{
aResult.Reset();
if (aAttribute == nsHTMLAtoms::multiple) {
return GetCacheAttribute(mMultiple, aResult, eHTMLUnit_Empty);
}
else {
return nsSelectSuper::GetAttribute(aAttribute, aResult);
}
}
PRInt32
nsSelect::GetMaxNumValues()
{
if (mMultiple) {
PRInt32 n;
ChildCount(n);
return n;
}
else {
return 1;
}
}
nsOption* nsSelect::GetNthOption(PRInt32 aIndex)
{
int optionX = -1;
PRInt32 numChildren;
ChildCount(numChildren);
for (int childX = 0; childX < numChildren; childX++) {
nsIContent* child;
ChildAt(childX, child);
nsOption* option;
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
if (NS_OK == result) {
optionX++;
if (aIndex == optionX) {
NS_RELEASE(child);
return option;
}
NS_RELEASE(option);
}
NS_RELEASE(child);
}
return nsnull;
}
PRBool
nsSelect::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if ((aMaxNumValues <= 0) || (nsnull == mName)) {
//NS_ASSERTION(0, "invalid max num values"); // XXX remove this in branch
return PR_FALSE;
}
if (!IsMultiple()) {
NS_ASSERTION(aMaxNumValues > 0, "invalid max num values");
nsIListWidget* list;
nsresult stat = mWidget->QueryInterface(kListWidgetIID, (void **) &list);
NS_ASSERTION((NS_OK == stat), "invalid widget");
PRInt32 index = list->GetSelectedIndex();
NS_RELEASE(list);
if (index >= 0) {
nsOption* selected = GetNthOption(index);
if (selected) {
selected->GetNamesValues(aMaxNumValues, aNumValues, aValues, aNames);
aNames[0] = *mName;
NS_RELEASE(selected); // YYY remove this comment if ok
return PR_TRUE;
}
}
else {
aNumValues = 0;
return PR_FALSE;
}
}
else {
nsIListBox* list;
nsresult stat = mWidget->QueryInterface(kListBoxIID, (void **) &list);
NS_ASSERTION((NS_OK == stat), "invalid widget");
PRInt32 numSelections = list->GetSelectedCount();
NS_ASSERTION(aMaxNumValues >= numSelections, "invalid max num values");
if (numSelections >= 0) {
PRInt32* selections = new PRInt32[numSelections];
list->GetSelectedIndices(selections, numSelections);
NS_RELEASE(list);
PRInt32 numValues;
aNumValues = 0;
for (int i = 0; i < numSelections; i++) {
nsOption* selected = GetNthOption(selections[i]);
if (selected) {
selected->GetNamesValues(aMaxNumValues - i, numValues,
aValues + i, aNames + i); // options can only have 1 value
aNames[i] = *mName;
aNumValues += 1;
NS_RELEASE(selected); // YYY remove this comment if ok
}
}
delete [] selections;
return PR_TRUE;
}
else {
aNumValues = 0;
return PR_FALSE;
}
}
aNumValues = 0;
return PR_FALSE;
}
void
nsSelect::Reset()
{
// PRBool allowMultiple;
// super::GetAttribute(nsHTMLAtoms::multiple, allowMultiple);
PRInt32 numChildren;
ChildCount(numChildren);
nsIListWidget* list;
nsresult stat = mWidget->QueryInterface(kListWidgetIID, (void **) &list);
NS_ASSERTION((NS_OK == stat), "invalid widget");
list->Deselect();
PRInt32 selIndex = -1;
int optionX = -1;
for (int childX = 0; childX < numChildren; childX++) {
nsIContent* child;
ChildAt(childX, child);
nsOption* option;
nsresult result = child->QueryInterface(kOptionIID, (void**)&option);
if (NS_OK == result) {
optionX++;
PRInt32 selAttr;
((nsInput *)option)->GetAttribute(nsHTMLAtoms::selected, selAttr);
if (ATTR_NOTSET != selAttr) {
list->SelectItem(optionX);
selIndex = optionX;
if (!mMultiple) {
break;
}
}
NS_RELEASE(option);
}
NS_RELEASE(child);
}
// if none were selected, select 1st one if we are a combo box
if (mIsComboBox && (numChildren > 0) && (selIndex < 0)) {
list->SelectItem(0);
}
NS_RELEASE(list);
}
// nsOption
nsOption::nsOption(nsIAtom* aTag)
: nsInput(aTag, nsnull)
{
mContent = nsnull;
mSelected = PR_FALSE;
}
nsOption::~nsOption()
{
if (nsnull != mContent) {
delete mContent;
}
}
void nsOption::GetType(nsString& aResult) const
{
aResult = "select";
}
nsresult nsOption::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (aIID.Equals(kOptionIID)) {
AddRef();
*aInstancePtr = (void**) this;
return NS_OK;
}
return nsInput::QueryInterface(aIID, aInstancePtr);
}
NS_IMETHODIMP
nsOption::SetAttribute(nsIAtom* aAttribute,
const nsString& aValue,
PRBool aNotify)
{
if (aAttribute == nsHTMLAtoms::selected) {
mSelected = PR_TRUE;
// XXX aNotify
return NS_OK;
}
else {
return nsOptionSuper::SetAttribute(aAttribute, aValue, aNotify);
}
}
NS_IMETHODIMP
nsOption::GetAttribute(nsIAtom* aAttribute,
nsHTMLValue& aResult) const
{
aResult.Reset();
if (aAttribute == nsHTMLAtoms::selected) {
return GetCacheAttribute(mSelected, aResult, eHTMLUnit_Empty);
}
else {
return nsOptionSuper::GetAttribute(aAttribute, aResult);
}
}
PRInt32
nsOption::GetMaxNumValues()
{
return 1;
}
PRBool nsOption::GetContent(nsString& aString) const
{
if (nsnull == mContent) {
aString.SetLength(0);
return PR_FALSE;
}
else {
aString = *mContent;
return PR_TRUE;
}
}
void nsOption::SetContent(const nsString& aString)
{
if (nsnull == mContent) {
mContent = new nsString();
}
*mContent = aString;
}
void
nsOption::CompressContent()
{
if (nsnull != mContent) {
mContent->CompressWhitespace(PR_TRUE, PR_TRUE);
}
}
PRBool
nsOption::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if (aMaxNumValues <= 0) {
NS_ASSERTION(aMaxNumValues > 0, "invalid max num values");
return PR_FALSE;
}
nsString valAttr;
nsresult stat = nsHTMLTagContent::GetAttribute(nsHTMLAtoms::value, valAttr);
if (NS_CONTENT_ATTR_HAS_VALUE == stat) {
aValues[0] = valAttr;
aNumValues = 1;
return PR_TRUE;
}
else if (nsnull != mContent) {
aValues[0] = *mContent;
aNumValues = 1;
return PR_TRUE;
}
else {
aNumValues = 0;
return PR_FALSE;
}
}
// FACTORY functions
nsresult
NS_NewHTMLSelect(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag, nsIFormManager* aFormMan)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsSelect(aTag, aFormMan);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}
nsresult
NS_NewHTMLOption(nsIHTMLContent** aInstancePtrResult,
nsIAtom* aTag)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
nsIHTMLContent* it = new nsOption(aTag);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIHTMLContentIID, (void**) aInstancePtrResult);
}

Просмотреть файл

@ -0,0 +1,581 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// YY need to pass isMultiple before create called
#include "nsFormControlFrame.h"
#include "nsIDOMNode.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsIRadioButton.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsHTMLAtoms.h"
#include "nsIView.h"
#include "nsIListWidget.h"
#include "nsIComboBox.h"
#include "nsIListBox.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsStyleUtil.h"
#include "nsFont.h"
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLCollectionIID, NS_IDOMHTMLCOLLECTION_IID);
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kListWidgetIID, NS_ILISTWIDGET_IID);
static NS_DEFINE_IID(kComboBoxIID, NS_ICOMBOBOX_IID);
static NS_DEFINE_IID(kListBoxIID, NS_ILISTBOX_IID);
static NS_DEFINE_IID(kComboCID, NS_COMBOBOX_CID);
static NS_DEFINE_IID(kListCID, NS_LISTBOX_CID);
class nsOption;
class nsSelectControlFrame : public nsFormControlFrame {
public:
nsSelectControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
NS_METHOD GetMultiple(PRBool* aResult, nsIDOMHTMLSelectElement* aSelect = nsnull);
virtual void Reset();
protected:
nsIDOMHTMLSelectElement* GetSelect();
nsIDOMHTMLCollection* GetOptions(nsIDOMHTMLSelectElement* aSelect = nsnull);
nsIDOMHTMLOptionElement* GetOption(nsIDOMHTMLCollection& aOptions, PRUint32 aIndex);
PRBool GetOptionValue(nsIDOMHTMLCollection& aCollecton, PRUint32 aIndex, nsString& aValue);
virtual ~nsSelectControlFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
PRBool mIsComboBox;
PRBool mOptionsAdded;
};
nsresult
NS_NewSelectControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsSelectControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsSelectControlFrame::nsSelectControlFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsFormControlFrame(aContent, aParentFrame)
{
mIsComboBox = PR_FALSE;
mOptionsAdded = PR_FALSE;
}
nsSelectControlFrame::~nsSelectControlFrame()
{
}
nscoord
nsSelectControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(1, aPixToTwip);
}
nscoord
nsSelectControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
nscoord
nsSelectControlFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
#ifdef XP_PC
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.15f);
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(1, aPixToTwip); // XXX this is probably wrong
#endif
}
PRInt32
nsSelectControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
#ifdef XP_PC
nscoord padding = (nscoord)NSToIntRound(float(aCharWidth) * 0.40f);
nscoord min = NSIntPixelsToTwips(3, aPixToTwip);
if (padding > min) {
return padding;
} else {
return min;
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(7, aPixToTwip); // XXX this is probably wrong
#endif
}
const nsIID&
nsSelectControlFrame::GetIID()
{
if (mIsComboBox) {
return kComboBoxIID;
} else {
return kListBoxIID;
}
}
const nsIID&
nsSelectControlFrame::GetCID()
{
if (mIsComboBox) {
return kComboCID;
} else {
return kListCID;
}
}
void
nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
nsIDOMHTMLSelectElement* select = GetSelect();
if (!select) {
return;
}
nsIDOMHTMLCollection* options = GetOptions(select);
if (!options) {
return;
}
// get the css size
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
// get the size of the longest option
PRInt32 maxWidth = 1;
PRUint32 numOptions;
options->GetLength(&numOptions);
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = GetOption(*options, i);
if (option) {
//option->CompressContent();
nsAutoString text;
if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
continue;
}
nsSize textSize;
// use the style for the select rather that the option, since widgets don't support it
nsFormControlFrame::GetTextSize(*aPresContext, this, text, textSize);
if (textSize.width > maxWidth) {
maxWidth = textSize.width;
}
NS_RELEASE(option);
}
}
PRInt32 rowHeight = 0;
nsSize calcSize, charSize;
PRBool widthExplicit, heightExplicit;
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull,
maxWidth, PR_TRUE, nsHTMLAtoms::size, 1);
// XXX fix CalculateSize to return PRUint32
PRUint32 numRows = (PRUint32)CalculateSize(aPresContext, this, styleSize, textSpec,
calcSize, widthExplicit, heightExplicit, rowHeight);
// here it is determined whether we are a combo box
PRInt32 sizeAttr;
GetSize(&sizeAttr);
PRBool multiple;
if (!GetMultiple(&multiple) &&
((1 >= sizeAttr) || ((ATTR_NOTSET == sizeAttr) && (1 >= numRows)))) {
mIsComboBox = PR_TRUE;
}
aDesiredLayoutSize.width = calcSize.width;
// account for vertical scrollbar, if present
if (!widthExplicit && ((numRows < numOptions) || mIsComboBox)) {
float p2t = aPresContext->GetPixelsToTwips();
aDesiredLayoutSize.width += GetScrollbarWidth(p2t);
}
// XXX put this in widget library, combo boxes are fixed height (visible part)
aDesiredLayoutSize.height = mIsComboBox ? 350 : calcSize.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height = aDesiredLayoutSize.height;
if (mIsComboBox) { // add in pull down size
aDesiredWidgetSize.height += (rowHeight * (numOptions > 20 ? 20 : numOptions)) + 100;
}
NS_RELEASE(options);
}
nsWidgetInitData*
nsSelectControlFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
if (mIsComboBox) {
nsComboBoxInitData* initData = new nsComboBoxInitData();
initData->clipChildren = PR_TRUE;
float twipToPix = aPresContext.GetTwipsToPixels();
initData->mDropDownHeight = NSTwipsToIntPixels(mWidgetSize.height, twipToPix);
return initData;
} else {
PRBool multiple;
GetMultiple(&multiple);
nsListBoxInitData* initData = nsnull;
if (multiple) {
initData = new nsListBoxInitData();
initData->clipChildren = PR_TRUE;
initData->mMultiSelect = PR_TRUE;
}
return initData;
}
}
NS_IMETHODIMP
nsSelectControlFrame::GetMultiple(PRBool* aMultiple, nsIDOMHTMLSelectElement* aSelect)
{
if (!aSelect) {
nsIDOMHTMLSelectElement* select = nsnull;
nsresult result = mContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&select);
if ((NS_OK == result) && select) {
result = select->GetMultiple(aMultiple);
NS_RELEASE(select);
}
return result;
} else {
return aSelect->GetMultiple(aMultiple);
}
}
nsIDOMHTMLSelectElement*
nsSelectControlFrame::GetSelect()
{
nsIDOMHTMLSelectElement* select = nsnull;
nsresult result = mContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&select);
if ((NS_OK == result) && select) {
return select;
} else {
return nsnull;
}
}
nsIDOMHTMLCollection*
nsSelectControlFrame::GetOptions(nsIDOMHTMLSelectElement* aSelect)
{
nsIDOMHTMLCollection* options = nsnull;
if (!aSelect) {
nsIDOMHTMLSelectElement* select = GetSelect();
if (select) {
select->GetOptions(&options);
NS_RELEASE(select);
return options;
} else {
return nsnull;
}
} else {
aSelect->GetOptions(&options);
return options;
}
}
void
nsSelectControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
{
if (!mWidget) {
return;
}
nsIListWidget* listWidget;
if (NS_OK != mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget)) {
NS_ASSERTION(PR_FALSE, "invalid widget");
return;
}
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
const nsStyleFont* styleFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
if ((styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT) ||
(styleFont->mFlags & NS_STYLE_FONT_SIZE_EXPLICIT)) {
nsFont widgetFont(styleFont->mFixedFont);
widgetFont.weight = NS_FONT_WEIGHT_NORMAL; // always normal weight
widgetFont.size = styleFont->mFont.size; // normal font size
if (0 == (styleFont->mFlags & NS_STYLE_FONT_FACE_EXPLICIT)) {
widgetFont.name = "Arial"; // XXX windows specific font
}
mWidget->SetFont(widgetFont);
} else {
// use arial, scaled down one HTML size
// italics, decoration & variant(?) get used
nsFont widgetFont(styleFont->mFont);
widgetFont.name = "Arial"; // XXX windows specific font
widgetFont.weight = NS_FONT_WEIGHT_NORMAL;
const nsFont& normal = aPresContext->GetDefaultFont();
PRInt32 scaler = aPresContext->GetFontScaler();
float scaleFactor = nsStyleUtil::GetScalingFactor(scaler);
PRInt32 fontIndex = nsStyleUtil::FindNextSmallerFontSize(widgetFont.size, (PRInt32)normal.size, scaleFactor);
widgetFont.size = nsStyleUtil::CalcFontPointSize(fontIndex, (PRInt32)normal.size, scaleFactor);
mWidget->SetFont(widgetFont);
}
// add the options
if (!mOptionsAdded) {
nsIDOMHTMLCollection* options = GetOptions();
if (options) {
PRUint32 numOptions;
options->GetLength(&numOptions);
nsIDOMNode* node;
nsIDOMHTMLOptionElement* option;
for (PRUint32 i = 0; i < numOptions; i++) {
options->Item(i, &node);
if (node) {
nsresult result = node->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option);
if ((NS_OK == result) && option) {
nsString text;
// XXX need to compress whitespace
if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
text = " ";
}
listWidget->AddItemAt(text, i);
NS_RELEASE(option);
}
NS_RELEASE(node);
}
}
NS_RELEASE(options);
}
mOptionsAdded = PR_TRUE;
}
NS_RELEASE(listWidget);
Reset(); // initializes selections
}
PRInt32
nsSelectControlFrame::GetMaxNumValues()
{
PRBool multiple;
GetMultiple(&multiple);
if (multiple) {
PRUint32 length = 0;
nsIDOMHTMLCollection* options = GetOptions();
if (options) {
options->GetLength(&length);
}
return (PRInt32)length; // XXX fix return on GetMaxNumValues
} else {
return 1;
}
}
PRBool
nsSelectControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
aNumValues = 0;
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) {
return PR_FALSE;
}
nsIDOMHTMLCollection* options = GetOptions();
if (!options) {
return PR_FALSE;
}
PRBool status = PR_FALSE;
PRBool multiple;
GetMultiple(&multiple);
if (!multiple) {
nsIListWidget* listWidget;
result = mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget);
if ((NS_OK == result) && listWidget) {
PRInt32 index = listWidget->GetSelectedIndex();
NS_RELEASE(listWidget);
if (index >= 0) {
nsAutoString value;
GetOptionValue(*options, index, value);
aNames[0] = name;
aValues[0] = value;
status = PR_TRUE;
}
}
} else {
nsIListBox* listBox;
nsresult result = mWidget->QueryInterface(kListBoxIID, (void **) &listBox);
if ((NS_OK == result) && listBox) {
PRInt32 numSelections = listBox->GetSelectedCount();
NS_ASSERTION(aMaxNumValues >= numSelections, "invalid max num values");
if (numSelections >= 0) {
PRInt32* selections = new PRInt32[numSelections];
listBox->GetSelectedIndices(selections, numSelections);
aNumValues = 0;
for (int i = 0; i < numSelections; i++) {
nsAutoString value;
GetOptionValue(*options, i, value);
aNames[i] = name;
aValues[i] = value;
aNumValues++;
}
delete[] selections;
status = PR_TRUE;
}
NS_RELEASE(listBox);
}
}
NS_RELEASE(options);
return status;
}
void
nsSelectControlFrame::Reset()
{
nsIDOMHTMLCollection* options = GetOptions();
if (!options) {
return;
}
PRBool multiple;
GetMultiple(&multiple);
PRUint32 numOptions;
options->GetLength(&numOptions);
PRInt32 selectedIndex = -1;
nsIListWidget* listWidget;
nsresult result = mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget);
if ((NS_OK == result) && listWidget) {
listWidget->Deselect();
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = GetOption(*options, i);
if (option) {
PRBool selected = PR_FALSE;
option->GetSelected(&selected);
if (selected) {
listWidget->SelectItem(i);
selectedIndex = i;
if (!multiple) {
break;
}
}
NS_RELEASE(option);
}
}
}
// if none were selected, select 1st one if we are a combo box
if (mIsComboBox && (numOptions > 0) && (selectedIndex < 0)) {
listWidget->SelectItem(0);
}
NS_RELEASE(listWidget);
NS_RELEASE(options);
}
/* XXX add this to nsHTMLOptionElement.cpp
void
nsOption::CompressContent()
{
if (nsnull != mContent) {
mContent->CompressWhitespace(PR_TRUE, PR_TRUE);
}
}*/
nsIDOMHTMLOptionElement*
nsSelectControlFrame::GetOption(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex)
{
nsIDOMNode* node = nsnull;
PRBool status = PR_FALSE;
if ((NS_OK == aCollection.Item(aIndex, &node)) && node) {
nsIDOMHTMLOptionElement* option = nsnull;
nsresult result = node->QueryInterface(kIDOMHTMLOptionElementIID, (void**)&option);
NS_RELEASE(node);
return option;
}
return nsnull;
}
PRBool
nsSelectControlFrame::GetOptionValue(nsIDOMHTMLCollection& aCollection, PRUint32 aIndex, nsString& aValue)
{
PRBool status = PR_FALSE;
nsIDOMHTMLOptionElement* option = GetOption(aCollection, aIndex);
if (option) {
if (NS_CONTENT_ATTR_HAS_VALUE == option->GetValue(aValue)) {
status = PR_TRUE;
} else {
if (NS_CONTENT_ATTR_HAS_VALUE == option->GetText(aValue)) {
status = PR_TRUE;
}
}
NS_RELEASE(option);
}
return status;
}

Просмотреть файл

@ -0,0 +1,374 @@
/* -*- 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 "nsTextControlFrame.h"
#include "nsIContent.h"
#include "prtypes.h"
#include "nsIFrame.h"
#include "nsISupports.h"
#include "nsIAtom.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLIIDs.h"
#include "nsITextWidget.h"
#include "nsITextAreaWidget.h"
#include "nsWidgetsCID.h"
#include "nsSize.h"
#include "nsString.h"
#include "nsHTMLAtoms.h"
#include "nsIStyleContext.h"
#include "nsFont.h"
#include "nsDOMEvent.h"
#include "nsIFormControl.h"
#include "nsFormFrame.h"
#include "nsIContent.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kTextCID, NS_TEXTFIELD_CID);
static NS_DEFINE_IID(kTextAreaCID, NS_TEXTAREA_CID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kITextAreaWidgetIID, NS_ITEXTAREAWIDGET_IID);
static NS_DEFINE_IID(kIDOMHTMLTextAreaElementIID, NS_IDOMHTMLTEXTAREAELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID);
nsresult
NS_NewTextControlFrame(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame*& aResult)
{
aResult = new nsTextControlFrame(aContent, aParent);
if (nsnull == aResult) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
nsTextControlFrame::nsTextControlFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsFormControlFrame(aContent, aParentFrame)
{
}
nsTextControlFrame::~nsTextControlFrame()
{
}
nscoord
nsTextControlFrame::GetVerticalBorderWidth(float aPixToTwip) const
{
return NSIntPixelsToTwips(4, aPixToTwip);
}
nscoord
nsTextControlFrame::GetHorizontalBorderWidth(float aPixToTwip) const
{
return GetVerticalBorderWidth(aPixToTwip);
}
// for a text area aInnerHeight is the height of one line
nscoord
nsTextControlFrame::GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const
{
#ifdef XP_PC
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.40f);
} else {
return (nscoord)NSToIntRound(float(aInnerHeight) * 0.25f);
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(10, aPixToTwip); // XXX this is probably wrong
#endif
}
nscoord
nsTextControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const
{
#ifdef XP_PC
nscoord padding;
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
padding = (nscoord)(40 * aCharWidth / 100);
} else {
padding = (nscoord)(55 * aCharWidth / 100);
}
nscoord min = NSIntPixelsToTwips(3, aPixToTwip);
if (padding > min) {
return padding;
} else {
return min;
}
#endif
#ifdef XP_UNIX
return NSIntPixelsToTwips(6, aPixToTwip); // XXX this is probably wrong
#endif
}
const nsIID&
nsTextControlFrame::GetIID()
{
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
return kITextAreaWidgetIID;
} else {
return kITextWidgetIID;
}
}
const nsIID&
nsTextControlFrame::GetCID()
{
PRInt32 type;
GetType(&type);
if (NS_FORM_TEXTAREA == type) {
return kTextAreaCID;
} else {
return kTextCID;
}
}
void
nsTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
{
if (mFormFrame && mFormFrame->CanSubmit(*this)) {
nsEventStatus mStatus = nsEventStatus_eIgnore;
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mFormFrame->OnSubmit(&aPresContext, this);
}
}
void
nsTextControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize)
{
// get the css size and let the frame use or override it
nsSize styleSize;
GetStyleSize(*aPresContext, aReflowState, styleSize);
nsSize size;
PRBool widthExplicit, heightExplicit;
PRInt32 ignore;
PRInt32 type;
GetType(&type);
if ((NS_FORM_INPUT_TEXT == type) || (NS_FORM_INPUT_PASSWORD == type)) {
PRInt32 width;
if (NS_CONTENT_ATTR_HAS_VALUE != GetSize(&width)) {
width = 20;
}
// Nav Quirk!!
width += 1;
nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull,
nsnull, width, PR_FALSE, nsnull, 1);
CalculateSize(aPresContext, this, styleSize, textSpec, size,
widthExplicit, heightExplicit, ignore);
} else {
nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, nsnull, 20,
PR_FALSE, nsHTMLAtoms::rows, 1);
CalculateSize(aPresContext, this, styleSize, areaSpec, size,
widthExplicit, heightExplicit, ignore);
}
if (NS_FORM_TEXTAREA == type) {
float p2t = aPresContext->GetPixelsToTwips();
nscoord scrollbarWidth = GetScrollbarWidth(p2t);
if (!heightExplicit) {
size.height += scrollbarWidth;
}
if (!widthExplicit) {
size.width += scrollbarWidth;
}
}
aDesiredLayoutSize.width = size.width;
aDesiredLayoutSize.height = size.height;
aDesiredLayoutSize.ascent = aDesiredLayoutSize.height;
aDesiredLayoutSize.descent = 0;
aDesiredWidgetSize.width = aDesiredLayoutSize.width;
aDesiredWidgetSize.height = aDesiredLayoutSize.height;
}
nsWidgetInitData*
nsTextControlFrame::GetWidgetInitData(nsIPresContext& aPresContext)
{
PRInt32 type;
GetType(&type);
nsTextWidgetInitData* data = nsnull;
if (NS_FORM_INPUT_PASSWORD == type) {
data = new nsTextWidgetInitData();
data->clipChildren = PR_TRUE;
data->mIsPassword = PR_TRUE;
}
return data;
}
NS_IMETHODIMP
nsTextControlFrame::GetText(nsString* aText)
{
nsresult result = NS_CONTENT_ATTR_NOT_THERE;
PRInt32 type;
GetType(&type);
if (NS_FORM_INPUT_TEXT == type) {
nsIDOMHTMLInputElement* textElem = nsnull;
nsresult result = mContent->QueryInterface(kIDOMHTMLInputElementIID, (void**)&textElem);
if ((NS_OK == result) && textElem) {
result = textElem->GetValue(*aText);
NS_RELEASE(textElem);
}
} else {
nsIDOMHTMLTextAreaElement* textArea = nsnull;
nsresult result = mContent->QueryInterface(kIDOMHTMLTextAreaElementIID, (void**)&textArea);
if ((NS_OK == result) && textArea) {
result = textArea->GetDefaultValue(*aText);
NS_RELEASE(textArea);
}
}
return result;
}
void
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
{
if (!mWidget) {
return;
}
PRInt32 type;
GetType(&type);
const nsStyleFont* fontStyle = (const nsStyleFont*)(mStyleContext->GetStyleData(eStyleStruct_Font));
mWidget->SetFont(fontStyle->mFixedFont);
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
PRUint32 ignore;
nsAutoString value;
GetText(&value);
nsITextAreaWidget* textArea = nsnull;
nsITextWidget* text = nsnull;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->SetText(value, ignore);
PRInt32 maxLength;
nsresult result = GetMaxLength(&maxLength);
if (NS_CONTENT_ATTR_NOT_THERE != result) {
text->SetMaxTextLength(maxLength);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->SetText(value, ignore);
mWidget->SetBackgroundColor(NS_RGB(0xFF, 0xFF, 0xFF));
NS_RELEASE(textArea);
}
}
PRInt32
nsTextControlFrame::GetMaxNumValues()
{
return 1;
}
PRBool
nsTextControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames)
{
if (!mWidget) {
return PR_FALSE;
}
nsAutoString name;
nsresult result = GetName(&name);
if ((aMaxNumValues <= 0) || (NS_CONTENT_ATTR_NOT_THERE == result)) {
return PR_FALSE;
}
PRUint32 size;
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
aNames[0] = name;
aNumValues = 1;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
text->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(text);
return PR_TRUE;
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
textArea->GetText(aValues[0],0,size); // the last parm is not used
NS_RELEASE(textArea);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsTextControlFrame::Reset()
{
if (!mWidget) {
return;
}
nsITextWidget* text = nsnull;
nsITextAreaWidget* textArea = nsnull;
nsAutoString value;
nsresult valStatus = GetText(&value);
PRUint32 size;
if (NS_OK == mWidget->QueryInterface(kITextWidgetIID,(void**)&text)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
text->SetText(value,size);
} else {
text->SetText("",size);
}
NS_RELEASE(text);
} else if (NS_OK == mWidget->QueryInterface(kITextAreaWidgetIID,(void**)&textArea)) {
if (NS_CONTENT_ATTR_HAS_VALUE == valStatus) {
textArea->SetText(value,size);
} else {
textArea->SetText("",size);
}
NS_RELEASE(textArea);
}
}

Просмотреть файл

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsTextControlFrame_h___
#define nsTextControlFrame_h___
#include "nsFormControlFrame.h"
class nsIContent;
class nsIFrame;
class nsIPresContext;
class nsTextControlFrame : public nsFormControlFrame {
public:
nsTextControlFrame(nsIContent* aContent, nsIFrame* aParentFrame);
virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext);
virtual void PostCreateWidget(nsIPresContext* aPresContext);
virtual const nsIID& GetCID();
virtual const nsIID& GetIID();
NS_IMETHOD GetText(nsString* aValue);
virtual void EnterPressed(nsIPresContext& aPresContext) ;
virtual nscoord GetVerticalBorderWidth(float aPixToTwip) const;
virtual nscoord GetHorizontalBorderWidth(float aPixToTwip) const;
virtual nscoord GetVerticalInsidePadding(float aPixToTwip,
nscoord aInnerHeight) const;
virtual nscoord GetHorizontalInsidePadding(nsIPresContext& aPresContext,
float aPixToTwip,
nscoord aInnerWidth,
nscoord aCharWidth) const;
virtual PRInt32 GetMaxNumValues();
virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
virtual void Reset();
protected:
virtual ~nsTextControlFrame();
virtual void GetDesiredSize(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
nsReflowMetrics& aDesiredLayoutSize,
nsSize& aDesiredWidgetSize);
};
#endif

Просмотреть файл

@ -948,40 +948,40 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent,
nsAutoString val;
if (NS_OK == aContent->GetAttribute(nsAutoString("type"), val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewInputCheckboxFrame(aContent, aParentFrame, aFrame);
rv = NS_NewCheckboxControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewInputFileFrame(aContent, aParentFrame, aFrame);
rv = NS_NewFileControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewInputRadioFrame(aContent, aParentFrame, aFrame);
rv = NS_NewRadioControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
} else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
return rv;
@ -1177,10 +1177,10 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = CreateInputFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::textarea == aTag) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aNewFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::select == aTag) {
rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, aNewFrame);
rv = NS_NewSelectControlFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::applet == aTag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, aNewFrame);
@ -1195,6 +1195,9 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = NS_NewBodyFrame(aContent, aParentFrame, aNewFrame);
processChildren = PR_TRUE;
}
else if (nsHTMLAtoms::form == aTag) {
rv = NS_NewFormFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::frameset == aTag) {
rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, aNewFrame);
}

Просмотреть файл

@ -948,40 +948,40 @@ HTMLStyleSheetImpl::CreateInputFrame(nsIContent* aContent,
nsAutoString val;
if (NS_OK == aContent->GetAttribute(nsAutoString("type"), val)) {
if (val.EqualsIgnoreCase("submit")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("reset")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("button")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("checkbox")) {
rv = NS_NewInputCheckboxFrame(aContent, aParentFrame, aFrame);
rv = NS_NewCheckboxControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("file")) {
rv = NS_NewInputFileFrame(aContent, aParentFrame, aFrame);
rv = NS_NewFileControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("hidden")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("image")) {
rv = NS_NewInputButtonFrame(aContent, aParentFrame, aFrame);
rv = NS_NewButtonControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("password")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("radio")) {
rv = NS_NewInputRadioFrame(aContent, aParentFrame, aFrame);
rv = NS_NewRadioControlFrame(aContent, aParentFrame, aFrame);
}
else if (val.EqualsIgnoreCase("text")) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
} else {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aFrame);
}
return rv;
@ -1177,10 +1177,10 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = CreateInputFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::textarea == aTag) {
rv = NS_NewInputTextFrame(aContent, aParentFrame, aNewFrame);
rv = NS_NewTextControlFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::select == aTag) {
rv = NS_NewHTMLSelectFrame(aContent, aParentFrame, aNewFrame);
rv = NS_NewSelectControlFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::applet == aTag) {
rv = NS_NewObjectFrame(aContent, aParentFrame, aNewFrame);
@ -1195,6 +1195,9 @@ HTMLStyleSheetImpl::ConstructFrameByTag(nsIPresContext* aPresContext,
rv = NS_NewBodyFrame(aContent, aParentFrame, aNewFrame);
processChildren = PR_TRUE;
}
else if (nsHTMLAtoms::form == aTag) {
rv = NS_NewFormFrame(aContent, aParentFrame, aNewFrame);
}
else if (nsHTMLAtoms::frameset == aTag) {
rv = NS_NewHTMLFramesetFrame(aContent, aParentFrame, aNewFrame);
}