Updating internal implementations to new DOM2 api syntax, capture/bubble functionality, new EventStateManager stuff (focus improvements)

This commit is contained in:
joki%netscape.com 1999-03-28 22:22:54 +00:00
parent 631f28bc50
commit 1c2882e5e6
52 changed files with 2087 additions and 884 deletions

View File

@ -677,6 +677,12 @@ nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMEventTargetIID)) {
nsIDOMEventTarget* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMNodeIID)) {
nsIDOMNode* tmp = this;
*aInstancePtr = (void*) tmp;
@ -1773,32 +1779,30 @@ nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext,
nsresult mRet = NS_OK;
nsIDOMEvent* mDOMEvent = nsnull;
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &mDOMEvent;
}
//Capturing stage
/*if (mEventCapturer) {
mEventCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}*/
if (NS_EVENT_FLAG_BUBBLE != aFlags) {
//XXX Check window capture here
}
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if (DOM_EVENT_CAPTURE != aFlags && nsnull != mScriptContextOwner) {
if (NS_EVENT_FLAG_CAPTURE != aFlags && nsnull != mScriptContextOwner) {
nsIScriptGlobalObject* mGlobal;
if (NS_OK == mScriptContextOwner->GetScriptGlobalObject(&mGlobal)) {
mGlobal->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, DOM_EVENT_BUBBLE, aEventStatus);
mGlobal->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_BUBBLE, aEventStatus);
NS_RELEASE(mGlobal);
}
}
/*Need to go to window here*/
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event, release here.
if (nsnull != *aDOMEvent) {
nsrefcnt rc;
@ -1819,22 +1823,51 @@ nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext,
return mRet;
}
nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
nsresult nsDocument::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsIEventListenerManager *mManager;
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&mManager)) {
mManager->AddEventListener(aListener, aIID);
NS_RELEASE(mManager);
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
nsresult nsDocument::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
if (nsnull != mListenerManager) {
mListenerManager->RemoveEventListener(aListener, aIID);
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;

View File

@ -25,6 +25,7 @@
#include "nsIScriptObjectOwner.h"
#include "nsIScriptContextOwner.h"
#include "nsIDOMEventCapturer.h"
#include "nsIDOMEventTarget.h"
#include "nsXIFConverter.h"
#include "nsIJSScriptObject.h"
#include "nsIContent.h"
@ -311,11 +312,18 @@ public:
NS_IMETHOD ReleaseEvent(const nsString& aType);
// nsIDOMEventReceiver interface
NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
// nsIDOMEventTarget interface
NS_IMETHOD AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
NS_IMETHOD RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,

View File

@ -61,6 +61,7 @@ nsGenericDOMDataNode::nsGenericDOMDataNode()
mScriptObject = nsnull;
mListenerManager = nsnull;
mRangeList = nsnull;
mCapturer = nsnull;
}
nsGenericDOMDataNode::~nsGenericDOMDataNode()
@ -428,13 +429,13 @@ nsGenericDOMDataNode::GetNewListenerManager(nsIEventListenerManager** aResult)
}
nsresult
nsGenericDOMDataNode::AddEventListener(nsIDOMEventListener* aListener,
nsGenericDOMDataNode::AddEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListener(aListener, aIID);
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(manager);
return NS_OK;
}
@ -442,11 +443,42 @@ nsGenericDOMDataNode::AddEventListener(nsIDOMEventListener* aListener,
}
nsresult
nsGenericDOMDataNode::RemoveEventListener(nsIDOMEventListener* aListener,
nsGenericDOMDataNode::RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
if (nsnull != mListenerManager) {
mListenerManager->RemoveEventListener(aListener, aIID);
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericDOMDataNode::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericDOMDataNode::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;
@ -652,26 +684,35 @@ nsGenericDOMDataNode::HandleDOMEvent(nsIPresContext& aPresContext,
nsEventStatus& aEventStatus)
{
nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull;
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &domEvent;
//Initiate capturing phase. Special case first call to document
if (nsnull != mDocument) {
mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
}
//Capturing stage
//Capturing stage evaluation
//Always pass capturing up the tree before local evaulation
if (NS_EVENT_FLAG_BUBBLE != aFlags && nsnull != mCapturer) {
mCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if (DOM_EVENT_CAPTURE != aFlags && mParent != nsnull) {
if (NS_EVENT_FLAG_CAPTURE != aFlags && mParent != nsnull) {
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
DOM_EVENT_BUBBLE, aEventStatus);
NS_EVENT_FLAG_BUBBLE, aEventStatus);
}
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event,
// release here.
if (nsnull != *aDOMEvent) {

View File

@ -30,6 +30,7 @@
extern const nsIID kIDOMCharacterDataIID;
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMEventReceiverIID;
extern const nsIID kIDOMEventTargetIID;
extern const nsIID kIScriptObjectOwnerIID;
extern const nsIID kISupportsIID;
extern const nsIID kIContentIID;
@ -102,12 +103,18 @@ struct nsGenericDOMDataNode {
nsresult ReplaceData(PRUint32 aOffset, PRUint32 aCount, const nsString& aArg);
// nsIDOMEventReceiver interface
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListener(nsIDOMEventListener* aListener,
nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID);
nsresult GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
nsresult GetNewListenerManager(nsIEventListenerManager** aInstancePtrResult);
// nsIDOMEventTarget interface
nsresult AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
nsresult RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
// nsIScriptObjectOwner interface
nsresult GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
nsresult SetScriptObject(void *aScriptObject);
@ -213,6 +220,7 @@ struct nsGenericDOMDataNode {
nsIContent* mParent;
void* mScriptObject;
nsIEventListenerManager* mListenerManager;
nsIContent* mCapturer;
nsTextFragment mText;
nsVoidArray *mRangeList;
@ -314,21 +322,33 @@ struct nsGenericDOMDataNode {
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListener(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListener(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
}
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
} \
NS_IMETHOD AddEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.AddEventListener(aType, aListener, aPostProcess, aUseCapture); \
} \
NS_IMETHOD RemoveEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.RemoveEventListener(aType, aListener, aPostProcess, aUseCapture); \
}
/**
* Implement the nsIScriptObjectOwner API by forwarding the methods to a
@ -474,6 +494,12 @@ struct nsGenericDOMDataNode {
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMEventTargetIID)) { \
nsIDOMEventTarget* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIScriptObjectOwnerIID)) { \
nsIScriptObjectOwner* tmp = _this; \
*_iptr = (void*) tmp; \

View File

@ -63,6 +63,7 @@ NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
NS_DEFINE_IID(kIDOMEventTargetIID, NS_IDOMEVENTTARGET_IID);
NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -206,6 +207,7 @@ nsGenericElement::GetDOMSlots()
mDOMSlots->mStyle = nsnull;
mDOMSlots->mAttributeMap = nsnull;
mDOMSlots->mRangeList = nsnull;
mDOMSlots->mCapturer = nsnull;
}
return mDOMSlots;
@ -737,24 +739,36 @@ nsGenericElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull;
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &domEvent;
//Initiate capturing phase
//Initiate capturing phase. Special case first call to document
if (nsnull != mDocument) {
mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
}
//Capturing stage
//Capturing stage evaluation
//Always pass capturing up the tree before local evaulation
if (NS_EVENT_FLAG_BUBBLE != aFlags) {
if (nsnull != mDOMSlots && nsnull != mDOMSlots->mCapturer) {
mDOMSlots->mCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
}
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull) && (mDocument != nsnull)) {
if ((NS_EVENT_FLAG_CAPTURE != aFlags) && (mParent != nsnull) && (mDocument != nsnull)) {
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
DOM_EVENT_BUBBLE, aEventStatus);
NS_EVENT_FLAG_BUBBLE, aEventStatus);
}
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event,
// release here.
if (nsnull != *aDOMEvent) {
@ -948,13 +962,13 @@ nsGenericElement::GetNewListenerManager(nsIEventListenerManager** aResult)
}
nsresult
nsGenericElement::AddEventListener(nsIDOMEventListener* aListener,
nsGenericElement::AddEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListener(aListener, aIID);
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(manager);
return NS_OK;
}
@ -962,11 +976,42 @@ nsGenericElement::AddEventListener(nsIDOMEventListener* aListener,
}
nsresult
nsGenericElement::RemoveEventListener(nsIDOMEventListener* aListener,
nsGenericElement::RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
if (nsnull != mListenerManager) {
mListenerManager->RemoveEventListener(aListener, aIID);
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericElement::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericElement::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;

View File

@ -33,6 +33,7 @@
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMElementIID;
extern const nsIID kIDOMEventReceiverIID;
extern const nsIID kIDOMEventTargetIID;
extern const nsIID kIScriptObjectOwnerIID;
extern const nsIID kIJSScriptObjectIID;
extern const nsIID kISupportsIID;
@ -79,6 +80,7 @@ typedef struct {
nsDOMCSSDeclaration *mStyle;
nsDOMAttributeMap* mAttributeMap;
nsVoidArray *mRangeList;
nsIContent* mCapturer;
} nsDOMSlots;
class nsGenericElement : public nsIJSScriptObject {
@ -116,12 +118,18 @@ public:
nsresult Normalize();
// nsIDOMEventReceiver interface
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListener(nsIDOMEventListener* aListener,
nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID);
nsresult GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
nsresult GetNewListenerManager(nsIEventListenerManager** aInstancePtrResult);
// nsIDOMEventTarget interface
nsresult AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
nsresult RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
// nsIScriptObjectOwner interface
nsresult GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
nsresult SetScriptObject(void *aScriptObject);
@ -373,21 +381,33 @@ public:
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(_g) \
NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListener(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListener(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
}
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(_g) \
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
} \
NS_IMETHOD AddEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.AddEventListener(aType, aListener, aPostProcess, aUseCapture); \
} \
NS_IMETHOD RemoveEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.RemoveEventListener(aType, aListener, aPostProcess, aUseCapture); \
}
#define NS_IMPL_ICONTENT_USING_GENERIC(_g) \
NS_IMETHOD GetDocument(nsIDocument*& aResult) const { \
@ -532,6 +552,12 @@ public:
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMEventTargetIID)) { \
nsIDOMEventTarget* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIScriptObjectOwnerIID)) { \
nsIScriptObjectOwner* tmp = _this; \
*_iptr = (void*) tmp; \

View File

@ -51,8 +51,29 @@ public:
* @param an event listener
*/
virtual nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) = 0;
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 flags) = 0;
/**
* Removes events listeners of all types.
* @param an event listener
*/
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 flags) = 0;
/**
* Sets events listeners of all types.
* @param an event listener
*/
virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 flags) = 0;
/**
* Removes events listeners of all types.
* @param an event listener
*/
virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 flags) = 0;
/**
* Creates a script event listener for the given script object with name mName and function
* content mFunc.
@ -70,21 +91,16 @@ public:
virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner,
REFNSIID aIID) = 0;
/**
* Removes events listeners of all types.
* @param an event listener
*/
virtual nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) = 0;
/**
* Causes a check for event listeners and processing by them if they exist.
* Event flags live in nsGUIEvent.h
* @param an event listener
*/
virtual nsresult HandleEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus) = 0;
/**

View File

@ -28,12 +28,6 @@ class nsIPresContext;
class nsIDOMEvent;
class nsIFrame;
enum nsLinkEventState {
eLinkState_Unspecified = 0,
eLinkState_Active = 1, // mouse is down on link
eLinkState_Hover = 2 // mouse is hovering over link
};
/*
* Event listener manager interface.
*/
@ -61,11 +55,16 @@ public:
NS_IMETHOD GetEventTarget(nsIFrame **aFrame) = 0;
NS_IMETHOD GetLinkState(nsIContent *aLink, nsLinkEventState& aState) = 0;
NS_IMETHOD SetActiveLink(nsIContent *aLink) = 0;
NS_IMETHOD SetHoverLink(nsIContent *aLink) = 0;
NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState) = 0;
NS_IMETHOD SetActiveContent(nsIContent *aActive) = 0;
NS_IMETHOD SetHoverContent(nsIContent *aHover) = 0;
NS_IMETHOD SetFocusedContent(nsIContent *aContent) = 0;
};
#define NS_EVENT_STATE_UNSPECIFIED 0000
#define NS_EVENT_STATE_ACTIVE 0001 // mouse is down on content
#define NS_EVENT_STATE_FOCUS 0002 // content has focus
#define NS_EVENT_STATE_HOVER 0003 // mouse is hovering over content
#endif // nsIEventStateManager_h__

View File

@ -261,6 +261,7 @@ NS_METHOD nsDOMEvent::GetCharCode(PRUint32* aCharCode)
{
switch (mEvent->message) {
case NS_KEY_UP:
case NS_KEY_PRESS:
case NS_KEY_DOWN:
*aCharCode = ((nsKeyEvent*)mEvent)->charCode;
#ifdef NS_DEBUG
@ -283,6 +284,7 @@ NS_METHOD nsDOMEvent::GetKeyCode(PRUint32* aKeyCode)
{
switch (mEvent->message) {
case NS_KEY_UP:
case NS_KEY_PRESS:
case NS_KEY_DOWN:
*aKeyCode = ((nsKeyEvent*)mEvent)->keyCode;
break;
@ -441,9 +443,9 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
return mEventNames[eDOMEvents_keydown];
case NS_KEY_PRESS:
return mEventNames[eDOMEvents_keypress];
case NS_GOTFOCUS:
case NS_FOCUS_CONTENT:
return mEventNames[eDOMEvents_focus];
case NS_LOSTFOCUS:
case NS_BLUR_CONTENT:
return mEventNames[eDOMEvents_blur];
case NS_PAGE_LOAD:
case NS_IMAGE_LOAD:

View File

@ -33,10 +33,6 @@ class nsIDOMRenderingContext;
class nsDOMEvent : public nsIDOMEvent, public nsIDOMNSEvent, public nsIPrivateDOMEvent {
#define DOM_EVENT_INIT 0x0001
#define DOM_EVENT_BUBBLE 0x0002
#define DOM_EVENT_CAPTURE 0x0004
public:
// Note: this enum must be kept in sync with mEventNames in nsDOMEvent.cpp
enum nsDOMEvents {

View File

@ -36,6 +36,7 @@
#include "nsIScriptObjectOwner.h"
#include "nsIScriptEventListener.h"
#include "nsDOMEventsIIDs.h"
#include "prmem.h"
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
@ -125,11 +126,12 @@ void nsEventListenerManager::ReleaseListeners(nsVoidArray* aListeners)
{
if (nsnull != aListeners) {
PRInt32 i, count = aListeners->Count();
nsIDOMEventListener *mElement;
nsListenerStruct *ls;
for (i = 0; i < count; i++) {
mElement = (nsIDOMEventListener *)aListeners->ElementAt(i);
if (mElement != nsnull) {
NS_RELEASE(mElement);
ls = (nsListenerStruct*)aListeners->ElementAt(i);
if (ls != nsnull) {
NS_IF_RELEASE(ls->mListener);
PR_DELETE(ls);
}
}
delete aListeners;
@ -149,24 +151,221 @@ nsresult nsEventListenerManager::GetEventListeners(nsVoidArray **aListeners, con
* Sets events listeners of all types.
* @param an event listener
*/
nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
const nsIID& aIID,
PRInt32 aFlags,
PRInt32 aSubType)
{
nsVoidArray** mListeners = GetListenersByIID(aIID);
nsVoidArray** listeners = GetListenersByIID(aIID);
if (nsnull == *mListeners) {
*mListeners = new nsVoidArray();
if (nsnull == *listeners) {
*listeners = new nsVoidArray();
}
if (nsnull == *mListeners) {
if (nsnull == *listeners) {
return NS_ERROR_OUT_OF_MEMORY;
}
(*mListeners)->InsertElementAt((void*)aListener, (*mListeners)->Count());
PRBool found = PR_FALSE;
nsListenerStruct* ls;
nsIScriptEventListener* sel = nsnull;
nsIScriptEventListener* regSel;
aListener->QueryInterface(kIScriptEventListenerIID, (void**)&sel);
for (int i=0; i<(*listeners)->Count(); i++) {
ls = (nsListenerStruct*)(*listeners)->ElementAt(i);
if (ls->mListener == aListener) {
ls->mFlags |= aFlags;
ls->mSubType |= aSubType;
found = PR_TRUE;
break;
}
else if (sel) {
if (NS_OK == ls->mListener->QueryInterface(kIScriptEventListenerIID, (void**)&regSel)) {
if (NS_OK == regSel->CheckIfEqual(sel)) {
if (ls->mFlags & aFlags && ls->mSubType & aSubType) {
found = PR_TRUE;
break;
}
}
}
}
}
if (!found) {
ls = PR_NEW(nsListenerStruct);
if (ls) {
ls->mListener = aListener;
ls->mFlags = aFlags;
ls->mSubType = aSubType;
(*listeners)->InsertElementAt((void*)ls, (*listeners)->Count());
}
}
NS_ADDREF(aListener);
return NS_OK;
}
nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
const nsIID& aIID,
PRInt32 aFlags,
PRInt32 aSubType)
{
nsVoidArray** listeners = GetListenersByIID(aIID);
if (nsnull == *listeners) {
return NS_OK;
}
nsListenerStruct* ls;
for (int i=0; i<(*listeners)->Count(); i++) {
ls = (nsListenerStruct*)(*listeners)->ElementAt(i);
if (ls->mListener == aListener) {
ls->mFlags &= ~aFlags;
ls->mSubType &= ~aSubType;
if (ls->mFlags == NS_EVENT_FLAG_NONE && ls->mSubType == NS_EVENT_BITS_NONE) {
NS_RELEASE(ls->mListener);
(*listeners)->RemoveElement((void*)ls);
PR_DELETE(ls);
}
break;
}
}
return NS_OK;
}
nsresult nsEventListenerManager::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID, PRInt32 aFlags)
{
AddEventListener(aListener, aIID, aFlags, NS_EVENT_BITS_NONE);
return NS_OK;
}
nsresult nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID, PRInt32 aFlags)
{
RemoveEventListener(aListener, aIID, aFlags, NS_EVENT_BITS_NONE);
return NS_OK;
}
nsresult nsEventListenerManager::GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aFlags)
{
if (aType == "mousedown") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEDOWN;
}
else if (aType == "mouseup") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEUP;
}
else if (aType == "click") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_CLICK;
}
else if (aType == "dblclick") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_DBLCLICK;
}
else if (aType == "mouseover") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEOVER;
}
else if (aType == "mouseout") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEOUT;
}
else if (aType == "keydown") {
aIID = kIDOMKeyListenerIID;
*aFlags = NS_EVENT_BITS_KEY_KEYDOWN;
}
else if (aType == "keyup") {
aIID = kIDOMKeyListenerIID;
*aFlags = NS_EVENT_BITS_KEY_KEYUP;
}
else if (aType == "keypress") {
aIID = kIDOMKeyListenerIID;
*aFlags = NS_EVENT_BITS_KEY_KEYPRESS;
}
else if (aType == "mousemove") {
aIID = kIDOMMouseMotionListenerIID;
*aFlags = NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE;
}
else if (aType == "focus") {
aIID = kIDOMFocusListenerIID;
*aFlags = NS_EVENT_BITS_FOCUS_FOCUS;
}
else if (aType == "blur") {
aIID = kIDOMFocusListenerIID;
*aFlags = NS_EVENT_BITS_FOCUS_BLUR;
}
else if (aType == "submit") {
aIID = kIDOMFormListenerIID;
*aFlags = NS_EVENT_BITS_FORM_SUBMIT;
}
else if (aType == "reset") {
aIID = kIDOMFormListenerIID;
*aFlags = NS_EVENT_BITS_FORM_RESET;
}
else if (aType == "change") {
aIID = kIDOMFormListenerIID;
*aFlags = NS_EVENT_BITS_FORM_CHANGE;
}
else if (aType == "load") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_LOAD;
}
else if (aType == "unload") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_UNLOAD;
}
else if (aType == "abort") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_ABORT;
}
else if (aType == "error") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_ERROR;
}
else if (aType == "paint") {
aIID = kIDOMPaintListenerIID;
*aFlags = NS_EVENT_BITS_PAINT_PAINT;
}
else {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aListener,
const nsString& aType, PRInt32 aFlags)
{
PRInt32 subType;
nsIID iid;
if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) {
AddEventListener(aListener, iid, aFlags, subType);
}
return NS_OK;
}
nsresult nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener,
const nsString& aType, PRInt32 aFlags)
{
PRInt32 subType;
nsIID iid;
if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) {
RemoveEventListener(aListener, iid, aFlags, subType);
}
return NS_OK;
}
const char *mEventArgv[] = {"event"};
nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID)
@ -177,20 +376,18 @@ nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
//Run through the listeners for this IID and see if a script listener is registered
//If so, we're set.
if (nsnull != mListeners) {
nsIScriptEventListener *mScriptListener;
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
for (int i=0; i<mListeners->Count(); i++) {
mEventListener = (nsIDOMEventListener*)mListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIScriptEventListenerIID, (void**)&mScriptListener)) {
NS_RELEASE(mScriptListener);
ls = (nsListenerStruct*)mListeners->ElementAt(i);
if (ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) {
return NS_OK;
}
}
}
//If we didn't find a script listener or no listeners existed create and add a new one.
nsIDOMEventListener *mScriptListener;
if (NS_OK == NS_NewScriptEventListener(&mScriptListener, aContext, aObject)) {
AddEventListener(mScriptListener, aIID);
if (NS_OK == NS_NewJSEventListener(&mScriptListener, aContext, aObject)) {
AddEventListenerByIID(mScriptListener, aIID, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT);
NS_RELEASE(mScriptListener);
return NS_OK;
}
@ -233,22 +430,6 @@ nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *a
return NS_ERROR_FAILURE;
}
/**
* Removes event listeners of all types.
* @param an event listener
*/
nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsVoidArray** mListeners = GetListenersByIID(aIID);
if (nsnull != *mListeners && PR_TRUE == (*mListeners)->RemoveElement((void*)aListener)) {
NS_RELEASE(aListener);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
/**
* Causes a check for event listeners and processing by them if they exist.
* @param an event listener
@ -257,9 +438,13 @@ nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListe
nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus)
{
nsresult ret = NS_OK;
if (aFlags & NS_EVENT_FLAG_INIT) {
aFlags |= NS_EVENT_FLAG_BUBBLE;
}
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
@ -282,46 +467,94 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mMouseListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMMouseListener *mMouseListener;
nsIScriptEventListener *scriptListener;
mEventListener = (nsIDOMEventListener*)mMouseListeners->ElementAt(i);
ls = (nsListenerStruct*)mMouseListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMMouseListenerIID, (void**)&mMouseListener)) {
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
ret = mMouseListener->MouseDown(*aDOMEvent);
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
ret = mMouseListener->MouseUp(*aDOMEvent);
break;
case NS_MOUSE_LEFT_CLICK:
case NS_MOUSE_MIDDLE_CLICK:
case NS_MOUSE_RIGHT_CLICK:
ret = mMouseListener->MouseClick(*aDOMEvent);
break;
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_MIDDLE_DOUBLECLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK:
ret = mMouseListener->MouseDblClick(*aDOMEvent);
break;
case NS_MOUSE_ENTER:
ret = mMouseListener->MouseOver(*aDOMEvent);
break;
case NS_MOUSE_EXIT:
ret = mMouseListener->MouseOut(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMMouseListenerIID, (void**)&mMouseListener)) {
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
ret = mMouseListener->MouseDown(*aDOMEvent);
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
ret = mMouseListener->MouseUp(*aDOMEvent);
break;
case NS_MOUSE_LEFT_CLICK:
case NS_MOUSE_MIDDLE_CLICK:
case NS_MOUSE_RIGHT_CLICK:
ret = mMouseListener->MouseClick(*aDOMEvent);
break;
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_MIDDLE_DOUBLECLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK:
ret = mMouseListener->MouseDblClick(*aDOMEvent);
break;
case NS_MOUSE_ENTER:
ret = mMouseListener->MouseOver(*aDOMEvent);
break;
case NS_MOUSE_EXIT:
ret = mMouseListener->MouseOut(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mMouseListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEDOWN) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEUP) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_LEFT_CLICK:
case NS_MOUSE_MIDDLE_CLICK:
case NS_MOUSE_RIGHT_CLICK:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_CLICK) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_MIDDLE_DOUBLECLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_DBLCLICK) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_ENTER:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOVER) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_EXIT:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOUT) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mMouseListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -336,23 +569,37 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mMouseMotionListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMMouseMotionListener *mMouseMotionListener;
mEventListener = (nsIDOMEventListener*)mMouseMotionListeners->ElementAt(i);
ls = (nsListenerStruct*)mMouseMotionListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMMouseMotionListenerIID, (void**)&mMouseMotionListener)) {
switch(aEvent->message) {
case NS_MOUSE_MOVE:
ret = mMouseMotionListener->MouseMove(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMMouseMotionListenerIID, (void**)&mMouseMotionListener)) {
switch(aEvent->message) {
case NS_MOUSE_MOVE:
ret = mMouseMotionListener->MouseMove(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mMouseMotionListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_MOUSE_MOVE:
if (ls->mSubType & NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mMouseMotionListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -362,28 +609,36 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
case NS_TEXT_EVENT:
#if DEBUG_TAGUE
printf("DOM: got text event\n");
printf("DOM: got text event\n");
#endif
if (nsnull != mTextListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent,aPresContext,aEvent);
}
if (NS_OK == ret) {
for (int i=0; i<mTextListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsIDOMTextListener *mTextListener;
if (nsnull != mTextListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent,aPresContext,aEvent);
}
if (NS_OK == ret) {
for (int i=0; i<mTextListeners->Count(); i++) {
nsListenerStruct *ls;
nsIDOMTextListener *mTextListener;
mEventListener = (nsIDOMEventListener*)mTextListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMTextListenerIID, (void**)&mTextListener)) {
ret = mTextListener->HandleText(*aDOMEvent);
NS_RELEASE(mTextListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
ls = (nsListenerStruct*)mTextListeners->ElementAt(i);
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMTextListenerIID, (void**)&mTextListener)) {
ret = mTextListener->HandleText(*aDOMEvent);
NS_RELEASE(mTextListener);
}
else {
PRBool correctSubType = PR_FALSE;
if (ls->mSubType & NS_EVENT_BITS_TEXT_TEXT) {
correctSubType = PR_TRUE;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
}
break;
@ -397,29 +652,53 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mKeyListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMKeyListener *mKeyListener;
mEventListener = (nsIDOMEventListener*)mKeyListeners->ElementAt(i);
ls = (nsListenerStruct*)mKeyListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMKeyListenerIID, (void**)&mKeyListener)) {
switch(aEvent->message) {
case NS_KEY_UP:
ret = mKeyListener->KeyUp(*aDOMEvent);
break;
case NS_KEY_DOWN:
ret = mKeyListener->KeyDown(*aDOMEvent);
break;
case NS_KEY_PRESS:
ret = mKeyListener->KeyPress(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMKeyListenerIID, (void**)&mKeyListener)) {
switch(aEvent->message) {
case NS_KEY_UP:
ret = mKeyListener->KeyUp(*aDOMEvent);
break;
case NS_KEY_DOWN:
ret = mKeyListener->KeyDown(*aDOMEvent);
break;
case NS_KEY_PRESS:
ret = mKeyListener->KeyPress(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mKeyListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_KEY_UP:
if (ls->mSubType & NS_EVENT_BITS_KEY_KEYUP) {
correctSubType = PR_TRUE;
}
break;
case NS_KEY_DOWN:
if (ls->mSubType & NS_EVENT_BITS_KEY_KEYDOWN) {
correctSubType = PR_TRUE;
}
break;
case NS_KEY_PRESS:
if (ls->mSubType & NS_EVENT_BITS_KEY_KEYPRESS) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mKeyListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -427,34 +706,53 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
break;
case NS_GOTFOCUS:
case NS_LOSTFOCUS:
case NS_FOCUS_CONTENT:
case NS_BLUR_CONTENT:
if (nsnull != mFocusListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
}
if (NS_OK == ret) {
for (int i=0; i<mFocusListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMFocusListener *mFocusListener;
mEventListener = (nsIDOMEventListener*)mFocusListeners->ElementAt(i);
ls = (nsListenerStruct*)mFocusListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMFocusListenerIID, (void**)&mFocusListener)) {
switch(aEvent->message) {
case NS_GOTFOCUS:
ret = mFocusListener->Focus(*aDOMEvent);
break;
case NS_LOSTFOCUS:
ret = mFocusListener->Blur(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMFocusListenerIID, (void**)&mFocusListener)) {
switch(aEvent->message) {
case NS_FOCUS_CONTENT:
ret = mFocusListener->Focus(*aDOMEvent);
break;
case NS_BLUR_CONTENT:
ret = mFocusListener->Blur(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mFocusListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_FOCUS_CONTENT:
if (ls->mSubType & NS_EVENT_BITS_FOCUS_FOCUS) {
correctSubType = PR_TRUE;
}
break;
case NS_BLUR_CONTENT:
if (ls->mSubType & NS_EVENT_BITS_FOCUS_BLUR) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mFocusListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -471,29 +769,53 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mFormListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMFormListener *mFormListener;
mEventListener = (nsIDOMEventListener*)mFormListeners->ElementAt(i);
ls = (nsListenerStruct*)mFormListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMFormListenerIID, (void**)&mFormListener)) {
switch(aEvent->message) {
case NS_FORM_SUBMIT:
ret = mFormListener->Submit(*aDOMEvent);
break;
case NS_FORM_RESET:
ret = mFormListener->Reset(*aDOMEvent);
break;
case NS_FORM_CHANGE:
ret = mFormListener->Change(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMFormListenerIID, (void**)&mFormListener)) {
switch(aEvent->message) {
case NS_FORM_SUBMIT:
ret = mFormListener->Submit(*aDOMEvent);
break;
case NS_FORM_RESET:
ret = mFormListener->Reset(*aDOMEvent);
break;
case NS_FORM_CHANGE:
ret = mFormListener->Change(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mFormListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_FORM_SUBMIT:
if (ls->mSubType & NS_EVENT_BITS_FORM_SUBMIT) {
correctSubType = PR_TRUE;
}
break;
case NS_FORM_RESET:
if (ls->mSubType & NS_EVENT_BITS_FORM_RESET) {
correctSubType = PR_TRUE;
}
break;
case NS_FORM_CHANGE:
if (ls->mSubType & NS_EVENT_BITS_FORM_CHANGE) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mFormListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -509,26 +831,45 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mLoadListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMLoadListener *mLoadListener;
mEventListener = (nsIDOMEventListener*)mLoadListeners->ElementAt(i);
ls = (nsListenerStruct*)mLoadListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMLoadListenerIID, (void**)&mLoadListener)) {
switch(aEvent->message) {
case NS_PAGE_LOAD:
ret = mLoadListener->Load(*aDOMEvent);
break;
case NS_PAGE_UNLOAD:
ret = mLoadListener->Unload(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMLoadListenerIID, (void**)&mLoadListener)) {
switch(aEvent->message) {
case NS_PAGE_LOAD:
ret = mLoadListener->Load(*aDOMEvent);
break;
case NS_PAGE_UNLOAD:
ret = mLoadListener->Unload(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mLoadListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_PAGE_LOAD:
if (ls->mSubType & NS_EVENT_BITS_LOAD_LOAD) {
correctSubType = PR_TRUE;
}
break;
case NS_PAGE_UNLOAD:
if (ls->mSubType & NS_EVENT_BITS_LOAD_UNLOAD) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mLoadListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -543,18 +884,26 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mPaintListeners->Count(); i++) {
nsIDOMEventListener *eventListener;
nsListenerStruct *ls;
nsIDOMPaintListener *paintListener;
eventListener = (nsIDOMEventListener*)mPaintListeners->ElementAt(i);
ls = (nsListenerStruct*)mPaintListeners->ElementAt(i);
if (NS_OK == eventListener->QueryInterface(kIDOMPaintListenerIID,
(void**)&paintListener)) {
ret = paintListener->Paint(*aDOMEvent);
NS_RELEASE(paintListener);
}
else {
ret = eventListener->ProcessEvent(*aDOMEvent);
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMPaintListenerIID,
(void**)&paintListener)) {
ret = paintListener->Paint(*aDOMEvent);
NS_RELEASE(paintListener);
}
else {
PRBool correctSubType = PR_FALSE;
if (ls->mSubType & NS_EVENT_BITS_PAINT_PAINT) {
correctSubType = PR_TRUE;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
}
aEventStatus = (NS_OK == ret)
? aEventStatus

View File

@ -23,7 +23,16 @@
#include "jsapi.h"
class nsIDOMEvent;
typedef struct {
nsIDOMEventListener* mListener;
PRUint8 mFlags;
PRUint8 mSubType;
} nsListenerStruct;
//Flag must live higher than all event flags in nsGUIEvent.h
#define NS_PRIV_EVENT_FLAG_SCRIPT 0x10
/*
* Event listener manager
*/
@ -52,7 +61,11 @@ public:
* @param an event listener
*/
virtual nsresult AddEventListener(nsIDOMEventListener *aListener, REFNSIID aIID);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags);
virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags);
virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags) ;
virtual nsresult AddScriptEventListener(nsIScriptContext* aContext,
nsIScriptObjectOwner *aScriptObjectOwner,
nsIAtom *aName,
@ -62,14 +75,14 @@ public:
nsIScriptObjectOwner *aScriptObjectOwner,
const nsIID& aIID);
virtual nsresult RemoveEventListener(nsIDOMEventListener *aListener, REFNSIID aIID);
virtual nsresult CaptureEvent(nsIDOMEventListener *aListener);
virtual nsresult ReleaseEvent(nsIDOMEventListener *aListener);
virtual nsresult HandleEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus);
virtual nsresult CreateEvent(nsIPresContext& aPresContext,
@ -78,6 +91,9 @@ public:
protected:
nsresult SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID);
nsresult GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aSubType);
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType);
nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType);
nsVoidArray* mEventListeners;
nsVoidArray* mMouseListeners;
@ -92,4 +108,61 @@ protected:
};
//Set of defines for distinguishing event hanlders within listener groupings
//XXX Current usage allows no more than 7 types per listener grouping
#define NS_EVENT_BITS_NONE 0x00
//nsIDOMMouseListener
#define NS_EVENT_BITS_MOUSE_NONE 0x00
#define NS_EVENT_BITS_MOUSE_MOUSEDOWN 0x01
#define NS_EVENT_BITS_MOUSE_MOUSEUP 0x02
#define NS_EVENT_BITS_MOUSE_CLICK 0x04
#define NS_EVENT_BITS_MOUSE_DBLCLICK 0x08
#define NS_EVENT_BITS_MOUSE_MOUSEOVER 0x10
#define NS_EVENT_BITS_MOUSE_MOUSEOUT 0x20
//nsIDOMMouseMotionListener
#define NS_EVENT_BITS_MOUSEMOTION_NONE 0x00
#define NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE 0x01
#define NS_EVENT_BITS_MOUSEMOTION_DRAGMOVE 0x02
//nsIDOMKeyListener
#define NS_EVENT_BITS_KEY_NONE 0x00
#define NS_EVENT_BITS_KEY_KEYDOWN 0x01
#define NS_EVENT_BITS_KEY_KEYUP 0x02
#define NS_EVENT_BITS_KEY_KEYPRESS 0x04
//nsIDOMTextListener
#define NS_EVENT_BITS_TEXT_NONE 0x00
#define NS_EVENT_BITS_TEXT_TEXT 0x01
//nsIDOMFocusListener
#define NS_EVENT_BITS_FOCUS_NONE 0x00
#define NS_EVENT_BITS_FOCUS_FOCUS 0x01
#define NS_EVENT_BITS_FOCUS_BLUR 0x02
//nsIDOMFormListener
#define NS_EVENT_BITS_FORM_NONE 0x00
#define NS_EVENT_BITS_FORM_SUBMIT 0x01
#define NS_EVENT_BITS_FORM_RESET 0x02
#define NS_EVENT_BITS_FORM_CHANGE 0x04
//nsIDOMLoadListener
#define NS_EVENT_BITS_LOAD_NONE 0x00
#define NS_EVENT_BITS_LOAD_LOAD 0x01
#define NS_EVENT_BITS_LOAD_UNLOAD 0x02
#define NS_EVENT_BITS_LOAD_ABORT 0x04
#define NS_EVENT_BITS_LOAD_ERROR 0x08
//nsIDOMDragListener
#define NS_EVENT_BITS_DRAG_NONE 0x00
#define NS_EVENT_BITS_DRAG_START 0x01
#define NS_EVENT_BITS_DRAG_DROP 0x02
//nsIDOMPaintListener
#define NS_EVENT_BITS_PAINT_NONE 0x00
#define NS_EVENT_BITS_PAINT_PAINT 0x01
#endif // nsEventListenerManager_h__

View File

@ -53,12 +53,12 @@ static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
nsEventStateManager::nsEventStateManager() {
mLastMouseOverFrame = nsnull;
mCurrentTarget = nsnull;
mLastLeftMouseDownFrame = nsnull;
mLastMiddleMouseDownFrame = nsnull;
mLastRightMouseDownFrame = nsnull;
mLastLeftMouseDownContent = nsnull;
mLastMiddleMouseDownContent = nsnull;
mLastRightMouseDownContent = nsnull;
mActiveLink = nsnull;
mHoverLink = nsnull;
mActiveContent = nsnull;
mHoverContent = nsnull;
mCurrentFocus = nsnull;
mDocument = nsnull;
mPresContext = nsnull;
@ -67,10 +67,13 @@ nsEventStateManager::nsEventStateManager() {
}
nsEventStateManager::~nsEventStateManager() {
NS_IF_RELEASE(mActiveLink);
NS_IF_RELEASE(mHoverLink);
NS_IF_RELEASE(mActiveContent);
NS_IF_RELEASE(mHoverContent);
NS_IF_RELEASE(mCurrentFocus);
NS_IF_RELEASE(mDocument);
NS_IF_RELEASE(mLastLeftMouseDownContent);
NS_IF_RELEASE(mLastMiddleMouseDownContent);
NS_IF_RELEASE(mLastRightMouseDownContent);
}
NS_IMPL_ADDREF(nsEventStateManager)
@ -98,7 +101,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext,
GenerateMouseEnterExit(aPresContext, aEvent);
break;
case NS_MOUSE_EXIT:
//GenerateMouseEnterExit(aPresContext, aEvent, aTargetFrame);
GenerateMouseEnterExit(aPresContext, aEvent);
break;
case NS_GOTFOCUS:
//XXX Do we need window related focus change stuff here?
@ -126,6 +129,8 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
{
ret = CheckForAndDispatchClick(aPresContext, (nsMouseEvent*)aEvent, aStatus);
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
if (newFocus) {
@ -137,12 +142,12 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
NS_RELEASE(newFocus);
}
}
//Break left out on purpose
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
mCurrentTarget = aTargetFrame;
ret = CheckForAndDispatchClick(aPresContext, (nsMouseEvent*)aEvent, aStatus);
SetActiveContent(nsnull);
break;
case NS_KEY_DOWN:
ret = DispatchKeyPressEvent(aPresContext, (nsKeyEvent*)aEvent, aStatus);
@ -182,15 +187,6 @@ nsEventStateManager::ClearFrameRefs(nsIFrame* aFrame)
if (aFrame == mCurrentTarget) {
mCurrentTarget = nsnull;
}
if (aFrame == mLastLeftMouseDownFrame) {
mLastLeftMouseDownFrame = nsnull;
}
if (aFrame == mLastMiddleMouseDownFrame) {
mLastMiddleMouseDownFrame = nsnull;
}
if (aFrame == mLastRightMouseDownFrame) {
mLastRightMouseDownFrame = nsnull;
}
return NS_OK;
}
@ -274,7 +270,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIE
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (nsnull != lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
@ -296,7 +292,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIE
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (nsnull != targetContent) {
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
@ -329,7 +325,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIE
mLastMouseOverFrame->GetContent(&lastContent);
if (nsnull != lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(lastContent);
}
@ -352,35 +348,44 @@ nsEventStateManager::CheckForAndDispatchClick(nsIPresContext& aPresContext,
{
nsresult ret = NS_OK;
nsMouseEvent event;
nsIContent* mouseContent;
PRBool fireClick = PR_FALSE;
mCurrentTarget->GetContent(&mouseContent);
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
mLastLeftMouseDownFrame = mCurrentTarget;
mLastLeftMouseDownContent = mouseContent;
NS_IF_ADDREF(mLastLeftMouseDownContent);
break;
case NS_MOUSE_LEFT_BUTTON_UP:
if (mLastLeftMouseDownFrame == mCurrentTarget) {
if (mLastLeftMouseDownContent == mouseContent) {
fireClick = PR_TRUE;
event.message = NS_MOUSE_LEFT_CLICK;
}
NS_IF_RELEASE(mLastLeftMouseDownContent);
break;
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
mLastMiddleMouseDownFrame = mCurrentTarget;
mLastMiddleMouseDownContent = mouseContent;
NS_IF_ADDREF(mLastMiddleMouseDownContent);
break;
case NS_MOUSE_MIDDLE_BUTTON_UP:
if (mLastMiddleMouseDownFrame == mCurrentTarget) {
if (mLastMiddleMouseDownContent == mouseContent) {
fireClick = PR_TRUE;
event.message = NS_MOUSE_MIDDLE_CLICK;
}
NS_IF_RELEASE(mLastMiddleMouseDownContent);
break;
case NS_MOUSE_RIGHT_BUTTON_DOWN:
mLastRightMouseDownFrame = mCurrentTarget;
mLastRightMouseDownContent = mouseContent;
NS_IF_ADDREF(mLastRightMouseDownContent);
break;
case NS_MOUSE_RIGHT_BUTTON_UP:
if (mLastRightMouseDownFrame == mCurrentTarget) {
if (mLastRightMouseDownContent == mouseContent) {
fireClick = PR_TRUE;
event.message = NS_MOUSE_RIGHT_CLICK;
}
NS_IF_RELEASE(mLastRightMouseDownContent);
break;
}
@ -389,17 +394,9 @@ nsEventStateManager::CheckForAndDispatchClick(nsIPresContext& aPresContext,
event.eventStructType = NS_MOUSE_EVENT;
event.widget = nsnull;
nsIContent *content;
mCurrentTarget->GetContent(&content);
if (nsnull != content) {
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, aStatus);
NS_RELEASE(content);
}
//Now dispatch to the frame
if (nsnull != mCurrentTarget) {
mCurrentTarget->HandleEvent(aPresContext, &event, aStatus);
if (nsnull != mouseContent) {
ret = mouseContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, aStatus);
NS_RELEASE(mouseContent);
}
}
return ret;
@ -423,7 +420,7 @@ nsEventStateManager::DispatchKeyPressEvent(nsIPresContext& aPresContext,
mCurrentTarget->GetContent(&content);
if (nsnull != content) {
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, aStatus);
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, aStatus);
NS_RELEASE(content);
}
@ -679,39 +676,45 @@ nsEventStateManager::GetEventTarget(nsIFrame **aFrame)
}
NS_IMETHODIMP
nsEventStateManager::GetLinkState(nsIContent *aLink, nsLinkEventState& aState)
nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState)
{
if (aLink == mActiveLink) {
aState = eLinkState_Active;
aState = NS_EVENT_STATE_UNSPECIFIED;
if (aContent == mActiveContent) {
aState |= NS_EVENT_STATE_ACTIVE;
}
else if (aLink == mHoverLink) {
aState = eLinkState_Hover;
if (aContent == mHoverContent) {
aState |= NS_EVENT_STATE_HOVER;
}
else {
aState = eLinkState_Unspecified;
if (aContent == mCurrentFocus) {
aState |= NS_EVENT_STATE_FOCUS;
}
return NS_OK;
}
NS_IMETHODIMP
nsEventStateManager::SetActiveLink(nsIContent *aLink)
nsEventStateManager::SetActiveContent(nsIContent *aActive)
{
nsIDocument *mDocument;
if (nsnull != mActiveLink) {
if (NS_OK == mActiveLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mActiveLink);
if (nsnull != mActiveContent) {
//transferring ref to lastActive from mActiveContent
nsIContent *lastActive = mActiveContent;
if (NS_OK == mActiveContent->GetDocument(mDocument)) {
mActiveContent = nsnull;
mDocument->ContentStateChanged(lastActive);
NS_RELEASE(mDocument);
}
NS_RELEASE(lastActive);
}
NS_IF_RELEASE(mActiveLink);
mActiveLink = aLink;
mActiveContent = aActive;
NS_IF_ADDREF(mActiveContent);
NS_IF_ADDREF(mActiveLink);
if (nsnull != mActiveLink) {
if (NS_OK == mActiveLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mActiveLink);
if (nsnull != mActiveContent) {
if (NS_OK == mActiveContent->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mActiveContent);
NS_RELEASE(mDocument);
}
}
@ -720,24 +723,28 @@ nsEventStateManager::SetActiveLink(nsIContent *aLink)
}
NS_IMETHODIMP
nsEventStateManager::SetHoverLink(nsIContent *aLink)
nsEventStateManager::SetHoverContent(nsIContent *aHover)
{
nsIDocument *mDocument;
if (nsnull != mHoverLink) {
if (NS_OK == mHoverLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mHoverLink);
if (nsnull != mHoverContent) {
//transferring ref to lastHover from mActiveContent
nsIContent *lastHover = mHoverContent;
if (NS_OK == mHoverContent->GetDocument(mDocument)) {
mHoverContent = nsnull;
mDocument->ContentStateChanged(lastHover);
NS_RELEASE(mDocument);
}
NS_RELEASE(lastHover);
}
NS_IF_RELEASE(mHoverLink);
mHoverLink = aLink;
mHoverContent = aHover;
NS_IF_ADDREF(mHoverLink);
if (nsnull != mHoverLink) {
if (NS_OK == mHoverLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mHoverLink);
NS_IF_ADDREF(mHoverContent);
if (nsnull != mHoverContent) {
if (NS_OK == mHoverContent->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mHoverContent);
NS_RELEASE(mDocument);
}
}
@ -762,7 +769,7 @@ nsEventStateManager::SetFocusedContent(nsIContent *aContent)
event.message = NS_BLUR_CONTENT;
if (nsnull != mPresContext) {
mCurrentFocus->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
mCurrentFocus->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
NS_RELEASE(mCurrentFocus);
}
@ -774,7 +781,7 @@ nsEventStateManager::SetFocusedContent(nsIContent *aContent)
event.message = NS_FOCUS_CONTENT;
if (nsnull != mPresContext) {
aContent->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
aContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
nsAutoString tabIndex;

View File

@ -50,10 +50,9 @@ public:
NS_IMETHOD GetEventTarget(nsIFrame **aFrame);
NS_IMETHOD GetLinkState(nsIContent *aLink, nsLinkEventState& aState);
NS_IMETHOD SetActiveLink(nsIContent *aLink);
NS_IMETHOD SetHoverLink(nsIContent *aLink);
NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState);
NS_IMETHOD SetActiveContent(nsIContent *aActive);
NS_IMETHOD SetHoverContent(nsIContent *aHover);
NS_IMETHOD SetFocusedContent(nsIContent *aContent);
protected:
@ -69,12 +68,13 @@ protected:
//Any frames here must be checked for validity in ClearFrameRefs
nsIFrame* mCurrentTarget;
nsIFrame* mLastMouseOverFrame;
nsIFrame* mLastLeftMouseDownFrame;
nsIFrame* mLastMiddleMouseDownFrame;
nsIFrame* mLastRightMouseDownFrame;
nsIContent* mActiveLink;
nsIContent* mHoverLink;
nsIContent* mLastLeftMouseDownContent;
nsIContent* mLastMiddleMouseDownContent;
nsIContent* mLastRightMouseDownContent;
nsIContent* mActiveContent;
nsIContent* mHoverContent;
nsIContent* mCurrentFocus;
PRInt32 mCurrentTabIndex;

View File

@ -283,39 +283,30 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->SetActiveLink(this);
NS_RELEASE(stateManager);
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->SetActiveContent(this);
NS_RELEASE(stateManager);
}
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
break;
case NS_MOUSE_LEFT_CLICK:
{
nsIEventStateManager *stateManager;
nsLinkEventState linkState;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->GetLinkState(this, linkState);
NS_RELEASE(stateManager);
}
if (eLinkState_Active == linkState) {
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString target;
nsIURL* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString target;
nsIURL* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;

View File

@ -1050,7 +1050,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
// first-child, lang, active, focus, hover, link, outOfDate, visited
// XXX disabled, enabled, selected, selection
nsAtomList* pseudoClass = aSelector->mPseudoClassList;
nsLinkEventState eventState = eLinkState_Unspecified;
PRInt32 eventState = NS_EVENT_STATE_UNSPECIFIED;
nsLinkState linkState = nsLinkState(-1); // not a link
nsILinkHandler* linkHandler = nsnull;
nsIEventStateManager* eventStateManager = nsnull;
@ -1092,18 +1092,17 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
if (! eventStateManager) {
aPresContext->GetEventStateManager(&eventStateManager);
if (eventStateManager) {
eventStateManager->GetLinkState(aContent, eventState);
eventStateManager->GetContentState(aContent, eventState);
}
}
if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) {
result = PRBool(0 != (eventState & eLinkState_Active));
result = PRBool(0 != (eventState & NS_EVENT_STATE_ACTIVE));
}
else if (nsCSSAtoms::focusPseudo == pseudoClass->mAtom) {
// result = PRBool(0 != (eventState & eLinkState_Focus));
result = PR_FALSE;
result = PRBool(0 != (eventState & NS_EVENT_STATE_FOCUS));
}
else if (nsCSSAtoms::hoverPseudo == pseudoClass->mAtom) {
result = PRBool(0 != (eventState & eLinkState_Hover));
result = PRBool(0 != (eventState & NS_EVENT_STATE_HOVER));
}
}
else if (IsLinkPseudo(pseudoClass->mAtom)) {

View File

@ -468,9 +468,9 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
(nsnull != eventStateManager)) {
nsLinkEventState state;
if (NS_OK == eventStateManager->GetLinkState(aContent, state)) {
if (0 != (state & eLinkState_Active)) {
PRInt32 state;
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
aResults->AppendElement(mActiveRule);
matchCount++;
}

View File

@ -136,45 +136,36 @@ nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->SetActiveLink(this);
stateManager->SetActiveContent(this);
NS_RELEASE(stateManager);
}
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_LEFT_CLICK:
{
nsIEventStateManager *stateManager;
nsLinkEventState linkState;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->GetLinkState(this, linkState);
NS_RELEASE(stateManager);
}
if (eLinkState_Active == linkState) {
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString show, href, target;
nsIURL* baseURL = nsnull;
nsLinkVerb verb = eLinkVerb_Replace;
target.Truncate();
GetAttribute(kNameSpaceID_None, kHrefAtom, href);
GetAttribute(kNameSpaceID_None, kShowAtom, show);
// XXX Should probably do this using atoms
if (show.Equals("new")) {
verb = eLinkVerb_New;
}
else if (show.Equals("embed")) {
verb = eLinkVerb_Embed;
}
if (nsnull != mInner.mDocument) {
baseURL = mInner.mDocument->GetDocumentURL();
}
mInner.TriggerLink(aPresContext, verb, baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString show, href, target;
nsIURL* baseURL = nsnull;
nsLinkVerb verb = eLinkVerb_Replace;
target.Truncate();
GetAttribute(kNameSpaceID_None, kHrefAtom, href);
GetAttribute(kNameSpaceID_None, kShowAtom, show);
// XXX Should probably do this using atoms
if (show.Equals("new")) {
verb = eLinkVerb_New;
}
else if (show.Equals("embed")) {
verb = eLinkVerb_Embed;
}
if (nsnull != mInner.mDocument) {
baseURL = mInner.mDocument->GetDocumentURL();
}
mInner.TriggerLink(aPresContext, verb, baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;
@ -184,7 +175,6 @@ nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
break;
case NS_MOUSE_ENTER:
//mouse enter doesn't work yet. Use move until then.
{
nsAutoString href, target;
nsIURL* baseURL = nsnull;

View File

@ -1964,7 +1964,7 @@ PresShell::HandleEvent(nsIView *aView,
nsIContent* targetContent;
if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) {
rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull,
DOM_EVENT_INIT, aEventStatus);
NS_EVENT_FLAG_INIT, aEventStatus);
NS_RELEASE(targetContent);
}

View File

@ -677,6 +677,12 @@ nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMEventTargetIID)) {
nsIDOMEventTarget* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDOMNodeIID)) {
nsIDOMNode* tmp = this;
*aInstancePtr = (void*) tmp;
@ -1773,32 +1779,30 @@ nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext,
nsresult mRet = NS_OK;
nsIDOMEvent* mDOMEvent = nsnull;
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &mDOMEvent;
}
//Capturing stage
/*if (mEventCapturer) {
mEventCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}*/
if (NS_EVENT_FLAG_BUBBLE != aFlags) {
//XXX Check window capture here
}
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if (DOM_EVENT_CAPTURE != aFlags && nsnull != mScriptContextOwner) {
if (NS_EVENT_FLAG_CAPTURE != aFlags && nsnull != mScriptContextOwner) {
nsIScriptGlobalObject* mGlobal;
if (NS_OK == mScriptContextOwner->GetScriptGlobalObject(&mGlobal)) {
mGlobal->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, DOM_EVENT_BUBBLE, aEventStatus);
mGlobal->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_BUBBLE, aEventStatus);
NS_RELEASE(mGlobal);
}
}
/*Need to go to window here*/
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event, release here.
if (nsnull != *aDOMEvent) {
nsrefcnt rc;
@ -1819,22 +1823,51 @@ nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext,
return mRet;
}
nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
nsresult nsDocument::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsIEventListenerManager *mManager;
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&mManager)) {
mManager->AddEventListener(aListener, aIID);
NS_RELEASE(mManager);
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
nsresult nsDocument::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
{
if (nsnull != mListenerManager) {
mListenerManager->RemoveEventListener(aListener, aIID);
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDocument::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;

View File

@ -25,6 +25,7 @@
#include "nsIScriptObjectOwner.h"
#include "nsIScriptContextOwner.h"
#include "nsIDOMEventCapturer.h"
#include "nsIDOMEventTarget.h"
#include "nsXIFConverter.h"
#include "nsIJSScriptObject.h"
#include "nsIContent.h"
@ -311,11 +312,18 @@ public:
NS_IMETHOD ReleaseEvent(const nsString& aType);
// nsIDOMEventReceiver interface
NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
// nsIDOMEventTarget interface
NS_IMETHOD AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
NS_IMETHOD RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,

View File

@ -61,6 +61,7 @@ nsGenericDOMDataNode::nsGenericDOMDataNode()
mScriptObject = nsnull;
mListenerManager = nsnull;
mRangeList = nsnull;
mCapturer = nsnull;
}
nsGenericDOMDataNode::~nsGenericDOMDataNode()
@ -428,13 +429,13 @@ nsGenericDOMDataNode::GetNewListenerManager(nsIEventListenerManager** aResult)
}
nsresult
nsGenericDOMDataNode::AddEventListener(nsIDOMEventListener* aListener,
nsGenericDOMDataNode::AddEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListener(aListener, aIID);
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(manager);
return NS_OK;
}
@ -442,11 +443,42 @@ nsGenericDOMDataNode::AddEventListener(nsIDOMEventListener* aListener,
}
nsresult
nsGenericDOMDataNode::RemoveEventListener(nsIDOMEventListener* aListener,
nsGenericDOMDataNode::RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
if (nsnull != mListenerManager) {
mListenerManager->RemoveEventListener(aListener, aIID);
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericDOMDataNode::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericDOMDataNode::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;
@ -652,26 +684,35 @@ nsGenericDOMDataNode::HandleDOMEvent(nsIPresContext& aPresContext,
nsEventStatus& aEventStatus)
{
nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull;
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &domEvent;
//Initiate capturing phase. Special case first call to document
if (nsnull != mDocument) {
mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
}
//Capturing stage
//Capturing stage evaluation
//Always pass capturing up the tree before local evaulation
if (NS_EVENT_FLAG_BUBBLE != aFlags && nsnull != mCapturer) {
mCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if (DOM_EVENT_CAPTURE != aFlags && mParent != nsnull) {
if (NS_EVENT_FLAG_CAPTURE != aFlags && mParent != nsnull) {
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
DOM_EVENT_BUBBLE, aEventStatus);
NS_EVENT_FLAG_BUBBLE, aEventStatus);
}
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event,
// release here.
if (nsnull != *aDOMEvent) {

View File

@ -30,6 +30,7 @@
extern const nsIID kIDOMCharacterDataIID;
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMEventReceiverIID;
extern const nsIID kIDOMEventTargetIID;
extern const nsIID kIScriptObjectOwnerIID;
extern const nsIID kISupportsIID;
extern const nsIID kIContentIID;
@ -102,12 +103,18 @@ struct nsGenericDOMDataNode {
nsresult ReplaceData(PRUint32 aOffset, PRUint32 aCount, const nsString& aArg);
// nsIDOMEventReceiver interface
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListener(nsIDOMEventListener* aListener,
nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID);
nsresult GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
nsresult GetNewListenerManager(nsIEventListenerManager** aInstancePtrResult);
// nsIDOMEventTarget interface
nsresult AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
nsresult RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
// nsIScriptObjectOwner interface
nsresult GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
nsresult SetScriptObject(void *aScriptObject);
@ -213,6 +220,7 @@ struct nsGenericDOMDataNode {
nsIContent* mParent;
void* mScriptObject;
nsIEventListenerManager* mListenerManager;
nsIContent* mCapturer;
nsTextFragment mText;
nsVoidArray *mRangeList;
@ -314,21 +322,33 @@ struct nsGenericDOMDataNode {
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListener(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListener(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
}
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC_DOM_DATA(_g) \
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
} \
NS_IMETHOD AddEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.AddEventListener(aType, aListener, aPostProcess, aUseCapture); \
} \
NS_IMETHOD RemoveEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.RemoveEventListener(aType, aListener, aPostProcess, aUseCapture); \
}
/**
* Implement the nsIScriptObjectOwner API by forwarding the methods to a
@ -474,6 +494,12 @@ struct nsGenericDOMDataNode {
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMEventTargetIID)) { \
nsIDOMEventTarget* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIScriptObjectOwnerIID)) { \
nsIScriptObjectOwner* tmp = _this; \
*_iptr = (void*) tmp; \

View File

@ -63,6 +63,7 @@ NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID);
NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID);
NS_DEFINE_IID(kIDOMEventTargetIID, NS_IDOMEVENTTARGET_IID);
NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
NS_DEFINE_IID(kIJSScriptObjectIID, NS_IJSSCRIPTOBJECT_IID);
NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
@ -206,6 +207,7 @@ nsGenericElement::GetDOMSlots()
mDOMSlots->mStyle = nsnull;
mDOMSlots->mAttributeMap = nsnull;
mDOMSlots->mRangeList = nsnull;
mDOMSlots->mCapturer = nsnull;
}
return mDOMSlots;
@ -737,24 +739,36 @@ nsGenericElement::HandleDOMEvent(nsIPresContext& aPresContext,
nsresult ret = NS_OK;
nsIDOMEvent* domEvent = nsnull;
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
aDOMEvent = &domEvent;
//Initiate capturing phase
//Initiate capturing phase. Special case first call to document
if (nsnull != mDocument) {
mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
}
//Capturing stage
//Capturing stage evaluation
//Always pass capturing up the tree before local evaulation
if (NS_EVENT_FLAG_BUBBLE != aFlags) {
if (nsnull != mDOMSlots && nsnull != mDOMSlots->mCapturer) {
mDOMSlots->mCapturer->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_CAPTURE, aEventStatus);
}
}
//Local handling stage
if (nsnull != mListenerManager) {
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aEventStatus);
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus);
}
//Bubbling stage
if ((DOM_EVENT_CAPTURE != aFlags) && (mParent != nsnull) && (mDocument != nsnull)) {
if ((NS_EVENT_FLAG_CAPTURE != aFlags) && (mParent != nsnull) && (mDocument != nsnull)) {
ret = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
DOM_EVENT_BUBBLE, aEventStatus);
NS_EVENT_FLAG_BUBBLE, aEventStatus);
}
if (DOM_EVENT_INIT == aFlags) {
if (NS_EVENT_FLAG_INIT == aFlags) {
// We're leaving the DOM event loop so if we created a DOM event,
// release here.
if (nsnull != *aDOMEvent) {
@ -948,13 +962,13 @@ nsGenericElement::GetNewListenerManager(nsIEventListenerManager** aResult)
}
nsresult
nsGenericElement::AddEventListener(nsIDOMEventListener* aListener,
nsGenericElement::AddEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
manager->AddEventListener(aListener, aIID);
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
NS_RELEASE(manager);
return NS_OK;
}
@ -962,11 +976,42 @@ nsGenericElement::AddEventListener(nsIDOMEventListener* aListener,
}
nsresult
nsGenericElement::RemoveEventListener(nsIDOMEventListener* aListener,
nsGenericElement::RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID)
{
if (nsnull != mListenerManager) {
mListenerManager->RemoveEventListener(aListener, aIID);
mListenerManager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericElement::AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
nsIEventListenerManager *manager;
if (NS_OK == GetListenerManager(&manager)) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
manager->AddEventListenerByType(aListener, aType, flags);
NS_RELEASE(manager);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult
nsGenericElement::RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture)
{
if (nsnull != mListenerManager) {
PRInt32 flags = (aPostProcess ? NS_EVENT_FLAG_POST_PROCESS : NS_EVENT_FLAG_NONE) |
(aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE);
mListenerManager->RemoveEventListenerByType(aListener, aType, flags);
return NS_OK;
}
return NS_ERROR_FAILURE;

View File

@ -33,6 +33,7 @@
extern const nsIID kIDOMNodeIID;
extern const nsIID kIDOMElementIID;
extern const nsIID kIDOMEventReceiverIID;
extern const nsIID kIDOMEventTargetIID;
extern const nsIID kIScriptObjectOwnerIID;
extern const nsIID kIJSScriptObjectIID;
extern const nsIID kISupportsIID;
@ -79,6 +80,7 @@ typedef struct {
nsDOMCSSDeclaration *mStyle;
nsDOMAttributeMap* mAttributeMap;
nsVoidArray *mRangeList;
nsIContent* mCapturer;
} nsDOMSlots;
class nsGenericElement : public nsIJSScriptObject {
@ -116,12 +118,18 @@ public:
nsresult Normalize();
// nsIDOMEventReceiver interface
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListener(nsIDOMEventListener* aListener,
nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
nsresult RemoveEventListenerByIID(nsIDOMEventListener* aListener,
const nsIID& aIID);
nsresult GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
nsresult GetNewListenerManager(nsIEventListenerManager** aInstancePtrResult);
// nsIDOMEventTarget interface
nsresult AddEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
nsresult RemoveEventListener(const nsString& aType, nsIDOMEventListener* aListener,
PRBool aPostProcess, PRBool aUseCapture);
// nsIScriptObjectOwner interface
nsresult GetScriptObject(nsIScriptContext* aContext, void** aScriptObject);
nsresult SetScriptObject(void *aScriptObject);
@ -373,21 +381,33 @@ public:
* generic content object (either nsGenericHTMLLeafElement or
* nsGenericHTMLContainerContent)
*/
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(_g) \
NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListener(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListener(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
}
#define NS_IMPL_IDOMEVENTRECEIVER_USING_GENERIC(_g) \
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.AddEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, \
const nsIID& aIID) { \
return _g.RemoveEventListenerByIID(aListener, aIID); \
} \
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetListenerManager(aResult); \
} \
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager** aResult) { \
return _g.GetNewListenerManager(aResult); \
} \
NS_IMETHOD AddEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.AddEventListener(aType, aListener, aPostProcess, aUseCapture); \
} \
NS_IMETHOD RemoveEventListener(const nsString& aType, \
nsIDOMEventListener* aListener, \
PRBool aPostProcess, \
PRBool aUseCapture) { \
return _g.RemoveEventListener(aType, aListener, aPostProcess, aUseCapture); \
}
#define NS_IMPL_ICONTENT_USING_GENERIC(_g) \
NS_IMETHOD GetDocument(nsIDocument*& aResult) const { \
@ -532,6 +552,12 @@ public:
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIDOMEventTargetIID)) { \
nsIDOMEventTarget* tmp = _this; \
*_iptr = (void*) tmp; \
NS_ADDREF_THIS(); \
return NS_OK; \
} \
if (_id.Equals(kIScriptObjectOwnerIID)) { \
nsIScriptObjectOwner* tmp = _this; \
*_iptr = (void*) tmp; \

View File

@ -51,8 +51,29 @@ public:
* @param an event listener
*/
virtual nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) = 0;
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 flags) = 0;
/**
* Removes events listeners of all types.
* @param an event listener
*/
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 flags) = 0;
/**
* Sets events listeners of all types.
* @param an event listener
*/
virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 flags) = 0;
/**
* Removes events listeners of all types.
* @param an event listener
*/
virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 flags) = 0;
/**
* Creates a script event listener for the given script object with name mName and function
* content mFunc.
@ -70,21 +91,16 @@ public:
virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aScriptObjectOwner,
REFNSIID aIID) = 0;
/**
* Removes events listeners of all types.
* @param an event listener
*/
virtual nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) = 0;
/**
* Causes a check for event listeners and processing by them if they exist.
* Event flags live in nsGUIEvent.h
* @param an event listener
*/
virtual nsresult HandleEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus) = 0;
/**

View File

@ -28,12 +28,6 @@ class nsIPresContext;
class nsIDOMEvent;
class nsIFrame;
enum nsLinkEventState {
eLinkState_Unspecified = 0,
eLinkState_Active = 1, // mouse is down on link
eLinkState_Hover = 2 // mouse is hovering over link
};
/*
* Event listener manager interface.
*/
@ -61,11 +55,16 @@ public:
NS_IMETHOD GetEventTarget(nsIFrame **aFrame) = 0;
NS_IMETHOD GetLinkState(nsIContent *aLink, nsLinkEventState& aState) = 0;
NS_IMETHOD SetActiveLink(nsIContent *aLink) = 0;
NS_IMETHOD SetHoverLink(nsIContent *aLink) = 0;
NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState) = 0;
NS_IMETHOD SetActiveContent(nsIContent *aActive) = 0;
NS_IMETHOD SetHoverContent(nsIContent *aHover) = 0;
NS_IMETHOD SetFocusedContent(nsIContent *aContent) = 0;
};
#define NS_EVENT_STATE_UNSPECIFIED 0000
#define NS_EVENT_STATE_ACTIVE 0001 // mouse is down on content
#define NS_EVENT_STATE_FOCUS 0002 // content has focus
#define NS_EVENT_STATE_HOVER 0003 // mouse is hovering over content
#endif // nsIEventStateManager_h__

View File

@ -261,6 +261,7 @@ NS_METHOD nsDOMEvent::GetCharCode(PRUint32* aCharCode)
{
switch (mEvent->message) {
case NS_KEY_UP:
case NS_KEY_PRESS:
case NS_KEY_DOWN:
*aCharCode = ((nsKeyEvent*)mEvent)->charCode;
#ifdef NS_DEBUG
@ -283,6 +284,7 @@ NS_METHOD nsDOMEvent::GetKeyCode(PRUint32* aKeyCode)
{
switch (mEvent->message) {
case NS_KEY_UP:
case NS_KEY_PRESS:
case NS_KEY_DOWN:
*aKeyCode = ((nsKeyEvent*)mEvent)->keyCode;
break;
@ -441,9 +443,9 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
return mEventNames[eDOMEvents_keydown];
case NS_KEY_PRESS:
return mEventNames[eDOMEvents_keypress];
case NS_GOTFOCUS:
case NS_FOCUS_CONTENT:
return mEventNames[eDOMEvents_focus];
case NS_LOSTFOCUS:
case NS_BLUR_CONTENT:
return mEventNames[eDOMEvents_blur];
case NS_PAGE_LOAD:
case NS_IMAGE_LOAD:

View File

@ -33,10 +33,6 @@ class nsIDOMRenderingContext;
class nsDOMEvent : public nsIDOMEvent, public nsIDOMNSEvent, public nsIPrivateDOMEvent {
#define DOM_EVENT_INIT 0x0001
#define DOM_EVENT_BUBBLE 0x0002
#define DOM_EVENT_CAPTURE 0x0004
public:
// Note: this enum must be kept in sync with mEventNames in nsDOMEvent.cpp
enum nsDOMEvents {

View File

@ -36,6 +36,7 @@
#include "nsIScriptObjectOwner.h"
#include "nsIScriptEventListener.h"
#include "nsDOMEventsIIDs.h"
#include "prmem.h"
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
@ -125,11 +126,12 @@ void nsEventListenerManager::ReleaseListeners(nsVoidArray* aListeners)
{
if (nsnull != aListeners) {
PRInt32 i, count = aListeners->Count();
nsIDOMEventListener *mElement;
nsListenerStruct *ls;
for (i = 0; i < count; i++) {
mElement = (nsIDOMEventListener *)aListeners->ElementAt(i);
if (mElement != nsnull) {
NS_RELEASE(mElement);
ls = (nsListenerStruct*)aListeners->ElementAt(i);
if (ls != nsnull) {
NS_IF_RELEASE(ls->mListener);
PR_DELETE(ls);
}
}
delete aListeners;
@ -149,24 +151,221 @@ nsresult nsEventListenerManager::GetEventListeners(nsVoidArray **aListeners, con
* Sets events listeners of all types.
* @param an event listener
*/
nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
const nsIID& aIID,
PRInt32 aFlags,
PRInt32 aSubType)
{
nsVoidArray** mListeners = GetListenersByIID(aIID);
nsVoidArray** listeners = GetListenersByIID(aIID);
if (nsnull == *mListeners) {
*mListeners = new nsVoidArray();
if (nsnull == *listeners) {
*listeners = new nsVoidArray();
}
if (nsnull == *mListeners) {
if (nsnull == *listeners) {
return NS_ERROR_OUT_OF_MEMORY;
}
(*mListeners)->InsertElementAt((void*)aListener, (*mListeners)->Count());
PRBool found = PR_FALSE;
nsListenerStruct* ls;
nsIScriptEventListener* sel = nsnull;
nsIScriptEventListener* regSel;
aListener->QueryInterface(kIScriptEventListenerIID, (void**)&sel);
for (int i=0; i<(*listeners)->Count(); i++) {
ls = (nsListenerStruct*)(*listeners)->ElementAt(i);
if (ls->mListener == aListener) {
ls->mFlags |= aFlags;
ls->mSubType |= aSubType;
found = PR_TRUE;
break;
}
else if (sel) {
if (NS_OK == ls->mListener->QueryInterface(kIScriptEventListenerIID, (void**)&regSel)) {
if (NS_OK == regSel->CheckIfEqual(sel)) {
if (ls->mFlags & aFlags && ls->mSubType & aSubType) {
found = PR_TRUE;
break;
}
}
}
}
}
if (!found) {
ls = PR_NEW(nsListenerStruct);
if (ls) {
ls->mListener = aListener;
ls->mFlags = aFlags;
ls->mSubType = aSubType;
(*listeners)->InsertElementAt((void*)ls, (*listeners)->Count());
}
}
NS_ADDREF(aListener);
return NS_OK;
}
nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
const nsIID& aIID,
PRInt32 aFlags,
PRInt32 aSubType)
{
nsVoidArray** listeners = GetListenersByIID(aIID);
if (nsnull == *listeners) {
return NS_OK;
}
nsListenerStruct* ls;
for (int i=0; i<(*listeners)->Count(); i++) {
ls = (nsListenerStruct*)(*listeners)->ElementAt(i);
if (ls->mListener == aListener) {
ls->mFlags &= ~aFlags;
ls->mSubType &= ~aSubType;
if (ls->mFlags == NS_EVENT_FLAG_NONE && ls->mSubType == NS_EVENT_BITS_NONE) {
NS_RELEASE(ls->mListener);
(*listeners)->RemoveElement((void*)ls);
PR_DELETE(ls);
}
break;
}
}
return NS_OK;
}
nsresult nsEventListenerManager::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID, PRInt32 aFlags)
{
AddEventListener(aListener, aIID, aFlags, NS_EVENT_BITS_NONE);
return NS_OK;
}
nsresult nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID, PRInt32 aFlags)
{
RemoveEventListener(aListener, aIID, aFlags, NS_EVENT_BITS_NONE);
return NS_OK;
}
nsresult nsEventListenerManager::GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aFlags)
{
if (aType == "mousedown") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEDOWN;
}
else if (aType == "mouseup") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEUP;
}
else if (aType == "click") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_CLICK;
}
else if (aType == "dblclick") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_DBLCLICK;
}
else if (aType == "mouseover") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEOVER;
}
else if (aType == "mouseout") {
aIID = kIDOMMouseListenerIID;
*aFlags = NS_EVENT_BITS_MOUSE_MOUSEOUT;
}
else if (aType == "keydown") {
aIID = kIDOMKeyListenerIID;
*aFlags = NS_EVENT_BITS_KEY_KEYDOWN;
}
else if (aType == "keyup") {
aIID = kIDOMKeyListenerIID;
*aFlags = NS_EVENT_BITS_KEY_KEYUP;
}
else if (aType == "keypress") {
aIID = kIDOMKeyListenerIID;
*aFlags = NS_EVENT_BITS_KEY_KEYPRESS;
}
else if (aType == "mousemove") {
aIID = kIDOMMouseMotionListenerIID;
*aFlags = NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE;
}
else if (aType == "focus") {
aIID = kIDOMFocusListenerIID;
*aFlags = NS_EVENT_BITS_FOCUS_FOCUS;
}
else if (aType == "blur") {
aIID = kIDOMFocusListenerIID;
*aFlags = NS_EVENT_BITS_FOCUS_BLUR;
}
else if (aType == "submit") {
aIID = kIDOMFormListenerIID;
*aFlags = NS_EVENT_BITS_FORM_SUBMIT;
}
else if (aType == "reset") {
aIID = kIDOMFormListenerIID;
*aFlags = NS_EVENT_BITS_FORM_RESET;
}
else if (aType == "change") {
aIID = kIDOMFormListenerIID;
*aFlags = NS_EVENT_BITS_FORM_CHANGE;
}
else if (aType == "load") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_LOAD;
}
else if (aType == "unload") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_UNLOAD;
}
else if (aType == "abort") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_ABORT;
}
else if (aType == "error") {
aIID = kIDOMLoadListenerIID;
*aFlags = NS_EVENT_BITS_LOAD_ERROR;
}
else if (aType == "paint") {
aIID = kIDOMPaintListenerIID;
*aFlags = NS_EVENT_BITS_PAINT_PAINT;
}
else {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult nsEventListenerManager::AddEventListenerByType(nsIDOMEventListener *aListener,
const nsString& aType, PRInt32 aFlags)
{
PRInt32 subType;
nsIID iid;
if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) {
AddEventListener(aListener, iid, aFlags, subType);
}
return NS_OK;
}
nsresult nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener,
const nsString& aType, PRInt32 aFlags)
{
PRInt32 subType;
nsIID iid;
if (NS_OK == GetIdentifiersForType(aType, iid, &subType)) {
RemoveEventListener(aListener, iid, aFlags, subType);
}
return NS_OK;
}
const char *mEventArgv[] = {"event"};
nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID)
@ -177,20 +376,18 @@ nsresult nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
//Run through the listeners for this IID and see if a script listener is registered
//If so, we're set.
if (nsnull != mListeners) {
nsIScriptEventListener *mScriptListener;
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
for (int i=0; i<mListeners->Count(); i++) {
mEventListener = (nsIDOMEventListener*)mListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIScriptEventListenerIID, (void**)&mScriptListener)) {
NS_RELEASE(mScriptListener);
ls = (nsListenerStruct*)mListeners->ElementAt(i);
if (ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) {
return NS_OK;
}
}
}
//If we didn't find a script listener or no listeners existed create and add a new one.
nsIDOMEventListener *mScriptListener;
if (NS_OK == NS_NewScriptEventListener(&mScriptListener, aContext, aObject)) {
AddEventListener(mScriptListener, aIID);
if (NS_OK == NS_NewJSEventListener(&mScriptListener, aContext, aObject)) {
AddEventListenerByIID(mScriptListener, aIID, NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT);
NS_RELEASE(mScriptListener);
return NS_OK;
}
@ -233,22 +430,6 @@ nsresult nsEventListenerManager::RegisterScriptEventListener(nsIScriptContext *a
return NS_ERROR_FAILURE;
}
/**
* Removes event listeners of all types.
* @param an event listener
*/
nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID)
{
nsVoidArray** mListeners = GetListenersByIID(aIID);
if (nsnull != *mListeners && PR_TRUE == (*mListeners)->RemoveElement((void*)aListener)) {
NS_RELEASE(aListener);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
/**
* Causes a check for event listeners and processing by them if they exist.
* @param an event listener
@ -257,9 +438,13 @@ nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListe
nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus)
{
nsresult ret = NS_OK;
if (aFlags & NS_EVENT_FLAG_INIT) {
aFlags |= NS_EVENT_FLAG_BUBBLE;
}
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
@ -282,46 +467,94 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mMouseListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMMouseListener *mMouseListener;
nsIScriptEventListener *scriptListener;
mEventListener = (nsIDOMEventListener*)mMouseListeners->ElementAt(i);
ls = (nsListenerStruct*)mMouseListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMMouseListenerIID, (void**)&mMouseListener)) {
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
ret = mMouseListener->MouseDown(*aDOMEvent);
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
ret = mMouseListener->MouseUp(*aDOMEvent);
break;
case NS_MOUSE_LEFT_CLICK:
case NS_MOUSE_MIDDLE_CLICK:
case NS_MOUSE_RIGHT_CLICK:
ret = mMouseListener->MouseClick(*aDOMEvent);
break;
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_MIDDLE_DOUBLECLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK:
ret = mMouseListener->MouseDblClick(*aDOMEvent);
break;
case NS_MOUSE_ENTER:
ret = mMouseListener->MouseOver(*aDOMEvent);
break;
case NS_MOUSE_EXIT:
ret = mMouseListener->MouseOut(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMMouseListenerIID, (void**)&mMouseListener)) {
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
ret = mMouseListener->MouseDown(*aDOMEvent);
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
ret = mMouseListener->MouseUp(*aDOMEvent);
break;
case NS_MOUSE_LEFT_CLICK:
case NS_MOUSE_MIDDLE_CLICK:
case NS_MOUSE_RIGHT_CLICK:
ret = mMouseListener->MouseClick(*aDOMEvent);
break;
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_MIDDLE_DOUBLECLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK:
ret = mMouseListener->MouseDblClick(*aDOMEvent);
break;
case NS_MOUSE_ENTER:
ret = mMouseListener->MouseOver(*aDOMEvent);
break;
case NS_MOUSE_EXIT:
ret = mMouseListener->MouseOut(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mMouseListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEDOWN) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEUP) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_LEFT_CLICK:
case NS_MOUSE_MIDDLE_CLICK:
case NS_MOUSE_RIGHT_CLICK:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_CLICK) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_LEFT_DOUBLECLICK:
case NS_MOUSE_MIDDLE_DOUBLECLICK:
case NS_MOUSE_RIGHT_DOUBLECLICK:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_DBLCLICK) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_ENTER:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOVER) {
correctSubType = PR_TRUE;
}
break;
case NS_MOUSE_EXIT:
if (ls->mSubType & NS_EVENT_BITS_MOUSE_MOUSEOUT) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mMouseListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -336,23 +569,37 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mMouseMotionListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMMouseMotionListener *mMouseMotionListener;
mEventListener = (nsIDOMEventListener*)mMouseMotionListeners->ElementAt(i);
ls = (nsListenerStruct*)mMouseMotionListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMMouseMotionListenerIID, (void**)&mMouseMotionListener)) {
switch(aEvent->message) {
case NS_MOUSE_MOVE:
ret = mMouseMotionListener->MouseMove(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMMouseMotionListenerIID, (void**)&mMouseMotionListener)) {
switch(aEvent->message) {
case NS_MOUSE_MOVE:
ret = mMouseMotionListener->MouseMove(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mMouseMotionListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_MOUSE_MOVE:
if (ls->mSubType & NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mMouseMotionListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -362,28 +609,36 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
case NS_TEXT_EVENT:
#if DEBUG_TAGUE
printf("DOM: got text event\n");
printf("DOM: got text event\n");
#endif
if (nsnull != mTextListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent,aPresContext,aEvent);
}
if (NS_OK == ret) {
for (int i=0; i<mTextListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsIDOMTextListener *mTextListener;
if (nsnull != mTextListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent,aPresContext,aEvent);
}
if (NS_OK == ret) {
for (int i=0; i<mTextListeners->Count(); i++) {
nsListenerStruct *ls;
nsIDOMTextListener *mTextListener;
mEventListener = (nsIDOMEventListener*)mTextListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMTextListenerIID, (void**)&mTextListener)) {
ret = mTextListener->HandleText(*aDOMEvent);
NS_RELEASE(mTextListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
ls = (nsListenerStruct*)mTextListeners->ElementAt(i);
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMTextListenerIID, (void**)&mTextListener)) {
ret = mTextListener->HandleText(*aDOMEvent);
NS_RELEASE(mTextListener);
}
else {
PRBool correctSubType = PR_FALSE;
if (ls->mSubType & NS_EVENT_BITS_TEXT_TEXT) {
correctSubType = PR_TRUE;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
}
break;
@ -397,29 +652,53 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mKeyListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMKeyListener *mKeyListener;
mEventListener = (nsIDOMEventListener*)mKeyListeners->ElementAt(i);
ls = (nsListenerStruct*)mKeyListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMKeyListenerIID, (void**)&mKeyListener)) {
switch(aEvent->message) {
case NS_KEY_UP:
ret = mKeyListener->KeyUp(*aDOMEvent);
break;
case NS_KEY_DOWN:
ret = mKeyListener->KeyDown(*aDOMEvent);
break;
case NS_KEY_PRESS:
ret = mKeyListener->KeyPress(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMKeyListenerIID, (void**)&mKeyListener)) {
switch(aEvent->message) {
case NS_KEY_UP:
ret = mKeyListener->KeyUp(*aDOMEvent);
break;
case NS_KEY_DOWN:
ret = mKeyListener->KeyDown(*aDOMEvent);
break;
case NS_KEY_PRESS:
ret = mKeyListener->KeyPress(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mKeyListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_KEY_UP:
if (ls->mSubType & NS_EVENT_BITS_KEY_KEYUP) {
correctSubType = PR_TRUE;
}
break;
case NS_KEY_DOWN:
if (ls->mSubType & NS_EVENT_BITS_KEY_KEYDOWN) {
correctSubType = PR_TRUE;
}
break;
case NS_KEY_PRESS:
if (ls->mSubType & NS_EVENT_BITS_KEY_KEYPRESS) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mKeyListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -427,34 +706,53 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
break;
case NS_GOTFOCUS:
case NS_LOSTFOCUS:
case NS_FOCUS_CONTENT:
case NS_BLUR_CONTENT:
if (nsnull != mFocusListeners) {
if (nsnull == *aDOMEvent) {
ret = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
}
if (NS_OK == ret) {
for (int i=0; i<mFocusListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMFocusListener *mFocusListener;
mEventListener = (nsIDOMEventListener*)mFocusListeners->ElementAt(i);
ls = (nsListenerStruct*)mFocusListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMFocusListenerIID, (void**)&mFocusListener)) {
switch(aEvent->message) {
case NS_GOTFOCUS:
ret = mFocusListener->Focus(*aDOMEvent);
break;
case NS_LOSTFOCUS:
ret = mFocusListener->Blur(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMFocusListenerIID, (void**)&mFocusListener)) {
switch(aEvent->message) {
case NS_FOCUS_CONTENT:
ret = mFocusListener->Focus(*aDOMEvent);
break;
case NS_BLUR_CONTENT:
ret = mFocusListener->Blur(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mFocusListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_FOCUS_CONTENT:
if (ls->mSubType & NS_EVENT_BITS_FOCUS_FOCUS) {
correctSubType = PR_TRUE;
}
break;
case NS_BLUR_CONTENT:
if (ls->mSubType & NS_EVENT_BITS_FOCUS_BLUR) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mFocusListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -471,29 +769,53 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mFormListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMFormListener *mFormListener;
mEventListener = (nsIDOMEventListener*)mFormListeners->ElementAt(i);
ls = (nsListenerStruct*)mFormListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMFormListenerIID, (void**)&mFormListener)) {
switch(aEvent->message) {
case NS_FORM_SUBMIT:
ret = mFormListener->Submit(*aDOMEvent);
break;
case NS_FORM_RESET:
ret = mFormListener->Reset(*aDOMEvent);
break;
case NS_FORM_CHANGE:
ret = mFormListener->Change(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMFormListenerIID, (void**)&mFormListener)) {
switch(aEvent->message) {
case NS_FORM_SUBMIT:
ret = mFormListener->Submit(*aDOMEvent);
break;
case NS_FORM_RESET:
ret = mFormListener->Reset(*aDOMEvent);
break;
case NS_FORM_CHANGE:
ret = mFormListener->Change(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mFormListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_FORM_SUBMIT:
if (ls->mSubType & NS_EVENT_BITS_FORM_SUBMIT) {
correctSubType = PR_TRUE;
}
break;
case NS_FORM_RESET:
if (ls->mSubType & NS_EVENT_BITS_FORM_RESET) {
correctSubType = PR_TRUE;
}
break;
case NS_FORM_CHANGE:
if (ls->mSubType & NS_EVENT_BITS_FORM_CHANGE) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mFormListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -509,26 +831,45 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mLoadListeners->Count(); i++) {
nsIDOMEventListener *mEventListener;
nsListenerStruct *ls;
nsIDOMLoadListener *mLoadListener;
mEventListener = (nsIDOMEventListener*)mLoadListeners->ElementAt(i);
ls = (nsListenerStruct*)mLoadListeners->ElementAt(i);
if (NS_OK == mEventListener->QueryInterface(kIDOMLoadListenerIID, (void**)&mLoadListener)) {
switch(aEvent->message) {
case NS_PAGE_LOAD:
ret = mLoadListener->Load(*aDOMEvent);
break;
case NS_PAGE_UNLOAD:
ret = mLoadListener->Unload(*aDOMEvent);
break;
default:
break;
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMLoadListenerIID, (void**)&mLoadListener)) {
switch(aEvent->message) {
case NS_PAGE_LOAD:
ret = mLoadListener->Load(*aDOMEvent);
break;
case NS_PAGE_UNLOAD:
ret = mLoadListener->Unload(*aDOMEvent);
break;
default:
break;
}
NS_RELEASE(mLoadListener);
}
else {
PRBool correctSubType = PR_FALSE;
switch(aEvent->message) {
case NS_PAGE_LOAD:
if (ls->mSubType & NS_EVENT_BITS_LOAD_LOAD) {
correctSubType = PR_TRUE;
}
break;
case NS_PAGE_UNLOAD:
if (ls->mSubType & NS_EVENT_BITS_LOAD_UNLOAD) {
correctSubType = PR_TRUE;
}
break;
default:
break;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
NS_RELEASE(mLoadListener);
}
else {
ret = mEventListener->ProcessEvent(*aDOMEvent);
}
aEventStatus = (NS_OK == ret) ? aEventStatus : nsEventStatus_eConsumeNoDefault;
}
@ -543,18 +884,26 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext,
}
if (NS_OK == ret) {
for (int i=0; i<mPaintListeners->Count(); i++) {
nsIDOMEventListener *eventListener;
nsListenerStruct *ls;
nsIDOMPaintListener *paintListener;
eventListener = (nsIDOMEventListener*)mPaintListeners->ElementAt(i);
ls = (nsListenerStruct*)mPaintListeners->ElementAt(i);
if (NS_OK == eventListener->QueryInterface(kIDOMPaintListenerIID,
(void**)&paintListener)) {
ret = paintListener->Paint(*aDOMEvent);
NS_RELEASE(paintListener);
}
else {
ret = eventListener->ProcessEvent(*aDOMEvent);
if (ls->mFlags & aFlags) {
if (NS_OK == ls->mListener->QueryInterface(kIDOMPaintListenerIID,
(void**)&paintListener)) {
ret = paintListener->Paint(*aDOMEvent);
NS_RELEASE(paintListener);
}
else {
PRBool correctSubType = PR_FALSE;
if (ls->mSubType & NS_EVENT_BITS_PAINT_PAINT) {
correctSubType = PR_TRUE;
}
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
ret = ls->mListener->HandleEvent(*aDOMEvent);
}
}
}
aEventStatus = (NS_OK == ret)
? aEventStatus

View File

@ -23,7 +23,16 @@
#include "jsapi.h"
class nsIDOMEvent;
typedef struct {
nsIDOMEventListener* mListener;
PRUint8 mFlags;
PRUint8 mSubType;
} nsListenerStruct;
//Flag must live higher than all event flags in nsGUIEvent.h
#define NS_PRIV_EVENT_FLAG_SCRIPT 0x10
/*
* Event listener manager
*/
@ -52,7 +61,11 @@ public:
* @param an event listener
*/
virtual nsresult AddEventListener(nsIDOMEventListener *aListener, REFNSIID aIID);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags);
virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags);
virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsString& type, PRInt32 aFlags) ;
virtual nsresult AddScriptEventListener(nsIScriptContext* aContext,
nsIScriptObjectOwner *aScriptObjectOwner,
nsIAtom *aName,
@ -62,14 +75,14 @@ public:
nsIScriptObjectOwner *aScriptObjectOwner,
const nsIID& aIID);
virtual nsresult RemoveEventListener(nsIDOMEventListener *aListener, REFNSIID aIID);
virtual nsresult CaptureEvent(nsIDOMEventListener *aListener);
virtual nsresult ReleaseEvent(nsIDOMEventListener *aListener);
virtual nsresult HandleEvent(nsIPresContext& aPresContext,
nsEvent* aEvent,
nsIDOMEvent** aDOMEvent,
nsIDOMEvent** aDOMEvent,
PRUint32 aFlags,
nsEventStatus& aEventStatus);
virtual nsresult CreateEvent(nsIPresContext& aPresContext,
@ -78,6 +91,9 @@ public:
protected:
nsresult SetJSEventListener(nsIScriptContext *aContext, JSObject *aObject, REFNSIID aIID);
nsresult GetIdentifiersForType(const nsString& aType, nsIID& aIID, PRInt32* aSubType);
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType);
nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType);
nsVoidArray* mEventListeners;
nsVoidArray* mMouseListeners;
@ -92,4 +108,61 @@ protected:
};
//Set of defines for distinguishing event hanlders within listener groupings
//XXX Current usage allows no more than 7 types per listener grouping
#define NS_EVENT_BITS_NONE 0x00
//nsIDOMMouseListener
#define NS_EVENT_BITS_MOUSE_NONE 0x00
#define NS_EVENT_BITS_MOUSE_MOUSEDOWN 0x01
#define NS_EVENT_BITS_MOUSE_MOUSEUP 0x02
#define NS_EVENT_BITS_MOUSE_CLICK 0x04
#define NS_EVENT_BITS_MOUSE_DBLCLICK 0x08
#define NS_EVENT_BITS_MOUSE_MOUSEOVER 0x10
#define NS_EVENT_BITS_MOUSE_MOUSEOUT 0x20
//nsIDOMMouseMotionListener
#define NS_EVENT_BITS_MOUSEMOTION_NONE 0x00
#define NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE 0x01
#define NS_EVENT_BITS_MOUSEMOTION_DRAGMOVE 0x02
//nsIDOMKeyListener
#define NS_EVENT_BITS_KEY_NONE 0x00
#define NS_EVENT_BITS_KEY_KEYDOWN 0x01
#define NS_EVENT_BITS_KEY_KEYUP 0x02
#define NS_EVENT_BITS_KEY_KEYPRESS 0x04
//nsIDOMTextListener
#define NS_EVENT_BITS_TEXT_NONE 0x00
#define NS_EVENT_BITS_TEXT_TEXT 0x01
//nsIDOMFocusListener
#define NS_EVENT_BITS_FOCUS_NONE 0x00
#define NS_EVENT_BITS_FOCUS_FOCUS 0x01
#define NS_EVENT_BITS_FOCUS_BLUR 0x02
//nsIDOMFormListener
#define NS_EVENT_BITS_FORM_NONE 0x00
#define NS_EVENT_BITS_FORM_SUBMIT 0x01
#define NS_EVENT_BITS_FORM_RESET 0x02
#define NS_EVENT_BITS_FORM_CHANGE 0x04
//nsIDOMLoadListener
#define NS_EVENT_BITS_LOAD_NONE 0x00
#define NS_EVENT_BITS_LOAD_LOAD 0x01
#define NS_EVENT_BITS_LOAD_UNLOAD 0x02
#define NS_EVENT_BITS_LOAD_ABORT 0x04
#define NS_EVENT_BITS_LOAD_ERROR 0x08
//nsIDOMDragListener
#define NS_EVENT_BITS_DRAG_NONE 0x00
#define NS_EVENT_BITS_DRAG_START 0x01
#define NS_EVENT_BITS_DRAG_DROP 0x02
//nsIDOMPaintListener
#define NS_EVENT_BITS_PAINT_NONE 0x00
#define NS_EVENT_BITS_PAINT_PAINT 0x01
#endif // nsEventListenerManager_h__

View File

@ -53,12 +53,12 @@ static NS_DEFINE_IID(kIFocusableContentIID, NS_IFOCUSABLECONTENT_IID);
nsEventStateManager::nsEventStateManager() {
mLastMouseOverFrame = nsnull;
mCurrentTarget = nsnull;
mLastLeftMouseDownFrame = nsnull;
mLastMiddleMouseDownFrame = nsnull;
mLastRightMouseDownFrame = nsnull;
mLastLeftMouseDownContent = nsnull;
mLastMiddleMouseDownContent = nsnull;
mLastRightMouseDownContent = nsnull;
mActiveLink = nsnull;
mHoverLink = nsnull;
mActiveContent = nsnull;
mHoverContent = nsnull;
mCurrentFocus = nsnull;
mDocument = nsnull;
mPresContext = nsnull;
@ -67,10 +67,13 @@ nsEventStateManager::nsEventStateManager() {
}
nsEventStateManager::~nsEventStateManager() {
NS_IF_RELEASE(mActiveLink);
NS_IF_RELEASE(mHoverLink);
NS_IF_RELEASE(mActiveContent);
NS_IF_RELEASE(mHoverContent);
NS_IF_RELEASE(mCurrentFocus);
NS_IF_RELEASE(mDocument);
NS_IF_RELEASE(mLastLeftMouseDownContent);
NS_IF_RELEASE(mLastMiddleMouseDownContent);
NS_IF_RELEASE(mLastRightMouseDownContent);
}
NS_IMPL_ADDREF(nsEventStateManager)
@ -98,7 +101,7 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext,
GenerateMouseEnterExit(aPresContext, aEvent);
break;
case NS_MOUSE_EXIT:
//GenerateMouseEnterExit(aPresContext, aEvent, aTargetFrame);
GenerateMouseEnterExit(aPresContext, aEvent);
break;
case NS_GOTFOCUS:
//XXX Do we need window related focus change stuff here?
@ -126,6 +129,8 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
case NS_MOUSE_RIGHT_BUTTON_DOWN:
{
ret = CheckForAndDispatchClick(aPresContext, (nsMouseEvent*)aEvent, aStatus);
nsIContent* newFocus;
mCurrentTarget->GetContent(&newFocus);
if (newFocus) {
@ -137,12 +142,12 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext,
NS_RELEASE(newFocus);
}
}
//Break left out on purpose
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_MIDDLE_BUTTON_UP:
case NS_MOUSE_RIGHT_BUTTON_UP:
mCurrentTarget = aTargetFrame;
ret = CheckForAndDispatchClick(aPresContext, (nsMouseEvent*)aEvent, aStatus);
SetActiveContent(nsnull);
break;
case NS_KEY_DOWN:
ret = DispatchKeyPressEvent(aPresContext, (nsKeyEvent*)aEvent, aStatus);
@ -182,15 +187,6 @@ nsEventStateManager::ClearFrameRefs(nsIFrame* aFrame)
if (aFrame == mCurrentTarget) {
mCurrentTarget = nsnull;
}
if (aFrame == mLastLeftMouseDownFrame) {
mLastLeftMouseDownFrame = nsnull;
}
if (aFrame == mLastMiddleMouseDownFrame) {
mLastMiddleMouseDownFrame = nsnull;
}
if (aFrame == mLastRightMouseDownFrame) {
mLastRightMouseDownFrame = nsnull;
}
return NS_OK;
}
@ -274,7 +270,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIE
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (nsnull != lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
@ -296,7 +292,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIE
if (lastContent != targetContent) {
//XXX This event should still go somewhere!!
if (nsnull != targetContent) {
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
@ -329,7 +325,7 @@ nsEventStateManager::GenerateMouseEnterExit(nsIPresContext& aPresContext, nsGUIE
mLastMouseOverFrame->GetContent(&lastContent);
if (nsnull != lastContent) {
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(lastContent);
}
@ -352,35 +348,44 @@ nsEventStateManager::CheckForAndDispatchClick(nsIPresContext& aPresContext,
{
nsresult ret = NS_OK;
nsMouseEvent event;
nsIContent* mouseContent;
PRBool fireClick = PR_FALSE;
mCurrentTarget->GetContent(&mouseContent);
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
mLastLeftMouseDownFrame = mCurrentTarget;
mLastLeftMouseDownContent = mouseContent;
NS_IF_ADDREF(mLastLeftMouseDownContent);
break;
case NS_MOUSE_LEFT_BUTTON_UP:
if (mLastLeftMouseDownFrame == mCurrentTarget) {
if (mLastLeftMouseDownContent == mouseContent) {
fireClick = PR_TRUE;
event.message = NS_MOUSE_LEFT_CLICK;
}
NS_IF_RELEASE(mLastLeftMouseDownContent);
break;
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
mLastMiddleMouseDownFrame = mCurrentTarget;
mLastMiddleMouseDownContent = mouseContent;
NS_IF_ADDREF(mLastMiddleMouseDownContent);
break;
case NS_MOUSE_MIDDLE_BUTTON_UP:
if (mLastMiddleMouseDownFrame == mCurrentTarget) {
if (mLastMiddleMouseDownContent == mouseContent) {
fireClick = PR_TRUE;
event.message = NS_MOUSE_MIDDLE_CLICK;
}
NS_IF_RELEASE(mLastMiddleMouseDownContent);
break;
case NS_MOUSE_RIGHT_BUTTON_DOWN:
mLastRightMouseDownFrame = mCurrentTarget;
mLastRightMouseDownContent = mouseContent;
NS_IF_ADDREF(mLastRightMouseDownContent);
break;
case NS_MOUSE_RIGHT_BUTTON_UP:
if (mLastRightMouseDownFrame == mCurrentTarget) {
if (mLastRightMouseDownContent == mouseContent) {
fireClick = PR_TRUE;
event.message = NS_MOUSE_RIGHT_CLICK;
}
NS_IF_RELEASE(mLastRightMouseDownContent);
break;
}
@ -389,17 +394,9 @@ nsEventStateManager::CheckForAndDispatchClick(nsIPresContext& aPresContext,
event.eventStructType = NS_MOUSE_EVENT;
event.widget = nsnull;
nsIContent *content;
mCurrentTarget->GetContent(&content);
if (nsnull != content) {
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, aStatus);
NS_RELEASE(content);
}
//Now dispatch to the frame
if (nsnull != mCurrentTarget) {
mCurrentTarget->HandleEvent(aPresContext, &event, aStatus);
if (nsnull != mouseContent) {
ret = mouseContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, aStatus);
NS_RELEASE(mouseContent);
}
}
return ret;
@ -423,7 +420,7 @@ nsEventStateManager::DispatchKeyPressEvent(nsIPresContext& aPresContext,
mCurrentTarget->GetContent(&content);
if (nsnull != content) {
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, aStatus);
ret = content->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, aStatus);
NS_RELEASE(content);
}
@ -679,39 +676,45 @@ nsEventStateManager::GetEventTarget(nsIFrame **aFrame)
}
NS_IMETHODIMP
nsEventStateManager::GetLinkState(nsIContent *aLink, nsLinkEventState& aState)
nsEventStateManager::GetContentState(nsIContent *aContent, PRInt32& aState)
{
if (aLink == mActiveLink) {
aState = eLinkState_Active;
aState = NS_EVENT_STATE_UNSPECIFIED;
if (aContent == mActiveContent) {
aState |= NS_EVENT_STATE_ACTIVE;
}
else if (aLink == mHoverLink) {
aState = eLinkState_Hover;
if (aContent == mHoverContent) {
aState |= NS_EVENT_STATE_HOVER;
}
else {
aState = eLinkState_Unspecified;
if (aContent == mCurrentFocus) {
aState |= NS_EVENT_STATE_FOCUS;
}
return NS_OK;
}
NS_IMETHODIMP
nsEventStateManager::SetActiveLink(nsIContent *aLink)
nsEventStateManager::SetActiveContent(nsIContent *aActive)
{
nsIDocument *mDocument;
if (nsnull != mActiveLink) {
if (NS_OK == mActiveLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mActiveLink);
if (nsnull != mActiveContent) {
//transferring ref to lastActive from mActiveContent
nsIContent *lastActive = mActiveContent;
if (NS_OK == mActiveContent->GetDocument(mDocument)) {
mActiveContent = nsnull;
mDocument->ContentStateChanged(lastActive);
NS_RELEASE(mDocument);
}
NS_RELEASE(lastActive);
}
NS_IF_RELEASE(mActiveLink);
mActiveLink = aLink;
mActiveContent = aActive;
NS_IF_ADDREF(mActiveContent);
NS_IF_ADDREF(mActiveLink);
if (nsnull != mActiveLink) {
if (NS_OK == mActiveLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mActiveLink);
if (nsnull != mActiveContent) {
if (NS_OK == mActiveContent->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mActiveContent);
NS_RELEASE(mDocument);
}
}
@ -720,24 +723,28 @@ nsEventStateManager::SetActiveLink(nsIContent *aLink)
}
NS_IMETHODIMP
nsEventStateManager::SetHoverLink(nsIContent *aLink)
nsEventStateManager::SetHoverContent(nsIContent *aHover)
{
nsIDocument *mDocument;
if (nsnull != mHoverLink) {
if (NS_OK == mHoverLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mHoverLink);
if (nsnull != mHoverContent) {
//transferring ref to lastHover from mActiveContent
nsIContent *lastHover = mHoverContent;
if (NS_OK == mHoverContent->GetDocument(mDocument)) {
mHoverContent = nsnull;
mDocument->ContentStateChanged(lastHover);
NS_RELEASE(mDocument);
}
NS_RELEASE(lastHover);
}
NS_IF_RELEASE(mHoverLink);
mHoverLink = aLink;
mHoverContent = aHover;
NS_IF_ADDREF(mHoverLink);
if (nsnull != mHoverLink) {
if (NS_OK == mHoverLink->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mHoverLink);
NS_IF_ADDREF(mHoverContent);
if (nsnull != mHoverContent) {
if (NS_OK == mHoverContent->GetDocument(mDocument)) {
mDocument->ContentStateChanged(mHoverContent);
NS_RELEASE(mDocument);
}
}
@ -762,7 +769,7 @@ nsEventStateManager::SetFocusedContent(nsIContent *aContent)
event.message = NS_BLUR_CONTENT;
if (nsnull != mPresContext) {
mCurrentFocus->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
mCurrentFocus->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
NS_RELEASE(mCurrentFocus);
}
@ -774,7 +781,7 @@ nsEventStateManager::SetFocusedContent(nsIContent *aContent)
event.message = NS_FOCUS_CONTENT;
if (nsnull != mPresContext) {
aContent->HandleDOMEvent(*mPresContext, &event, nsnull, DOM_EVENT_INIT, status);
aContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
nsAutoString tabIndex;

View File

@ -50,10 +50,9 @@ public:
NS_IMETHOD GetEventTarget(nsIFrame **aFrame);
NS_IMETHOD GetLinkState(nsIContent *aLink, nsLinkEventState& aState);
NS_IMETHOD SetActiveLink(nsIContent *aLink);
NS_IMETHOD SetHoverLink(nsIContent *aLink);
NS_IMETHOD GetContentState(nsIContent *aContent, PRInt32& aState);
NS_IMETHOD SetActiveContent(nsIContent *aActive);
NS_IMETHOD SetHoverContent(nsIContent *aHover);
NS_IMETHOD SetFocusedContent(nsIContent *aContent);
protected:
@ -69,12 +68,13 @@ protected:
//Any frames here must be checked for validity in ClearFrameRefs
nsIFrame* mCurrentTarget;
nsIFrame* mLastMouseOverFrame;
nsIFrame* mLastLeftMouseDownFrame;
nsIFrame* mLastMiddleMouseDownFrame;
nsIFrame* mLastRightMouseDownFrame;
nsIContent* mActiveLink;
nsIContent* mHoverLink;
nsIContent* mLastLeftMouseDownContent;
nsIContent* mLastMiddleMouseDownContent;
nsIContent* mLastRightMouseDownContent;
nsIContent* mActiveContent;
nsIContent* mHoverContent;
nsIContent* mCurrentFocus;
PRInt32 mCurrentTabIndex;

View File

@ -337,7 +337,7 @@ nsHTMLButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_RESET;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, NS_EVENT_FLAG_INIT, mStatus);
mFormFrame->OnReset();
} else if (NS_FORM_BUTTON_SUBMIT == type) {
@ -346,7 +346,7 @@ nsHTMLButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, NS_EVENT_FLAG_INIT, mStatus);
mFormFrame->OnSubmit(aPresContext, this);
}

View File

@ -360,7 +360,7 @@ nsImageControlFrame::MouseClicked(nsIPresContext* aPresContext)
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
if (nsnull != formContent) {
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}
if (nsEventStatus_eConsumeNoDefault != status) {

View File

@ -1437,3 +1437,4 @@ nsresult nsListControlFrame::RequiresWidget(PRBool& aRequiresWidget)
}

View File

@ -89,7 +89,7 @@ public:
/*virtual nsresult Focus(nsIDOMEvent* aEvent);
virtual nsresult Blur(nsIDOMEvent* aEvent);
virtual nsresult ProcessEvent(nsIDOMEvent* aEvent);
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
NS_IMETHOD AddEventListener(nsIDOMNode * aNode);
NS_IMETHOD RemoveEventListener(nsIDOMNode * aNode);

View File

@ -218,7 +218,7 @@ nsTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
formContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
formContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}

View File

@ -1964,7 +1964,7 @@ PresShell::HandleEvent(nsIView *aView,
nsIContent* targetContent;
if (NS_OK == mCurrentEventFrame->GetContent(&targetContent) && nsnull != targetContent) {
rv = targetContent->HandleDOMEvent(*mPresContext, (nsEvent*)aEvent, nsnull,
DOM_EVENT_INIT, aEventStatus);
NS_EVENT_FLAG_INIT, aEventStatus);
NS_RELEASE(targetContent);
}

View File

@ -283,39 +283,30 @@ nsHTMLAnchorElement::HandleDOMEvent(nsIPresContext& aPresContext,
if (NS_CONTENT_ATTR_HAS_VALUE == result) {
switch (aEvent->message) {
case NS_MOUSE_LEFT_BUTTON_DOWN:
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->SetActiveLink(this);
NS_RELEASE(stateManager);
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->SetActiveContent(this);
NS_RELEASE(stateManager);
}
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
break;
case NS_MOUSE_LEFT_CLICK:
{
nsIEventStateManager *stateManager;
nsLinkEventState linkState;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->GetLinkState(this, linkState);
NS_RELEASE(stateManager);
}
if (eLinkState_Active == linkState) {
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString target;
nsIURL* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString target;
nsIURL* baseURL = nsnull;
GetBaseURL(baseURL);
GetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::target, target);
if (target.Length() == 0) {
GetBaseTarget(target);
}
mInner.TriggerLink(aPresContext, eLinkVerb_Replace,
baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;

View File

@ -322,7 +322,7 @@ nsButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
case NS_FORM_INPUT_RESET:
event.message = NS_FORM_RESET;
if (nsnull != formContent) {
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
if (nsEventStatus_eConsumeNoDefault != status) {
mFormFrame->OnReset();
@ -331,7 +331,7 @@ nsButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
case NS_FORM_INPUT_SUBMIT:
event.message = NS_FORM_SUBMIT;
if (nsnull != formContent) {
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
if (nsEventStatus_eConsumeNoDefault != status) {
mFormFrame->OnSubmit(aPresContext, this);

View File

@ -337,7 +337,7 @@ nsHTMLButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_RESET;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, NS_EVENT_FLAG_INIT, mStatus);
mFormFrame->OnReset();
} else if (NS_FORM_BUTTON_SUBMIT == type) {
@ -346,7 +346,7 @@ nsHTMLButtonControlFrame::MouseClicked(nsIPresContext* aPresContext)
nsEvent mEvent;
mEvent.eventStructType = NS_EVENT;
mEvent.message = NS_FORM_SUBMIT;
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus);
mContent->HandleDOMEvent(*aPresContext, &mEvent, nsnull, NS_EVENT_FLAG_INIT, mStatus);
mFormFrame->OnSubmit(aPresContext, this);
}

View File

@ -360,7 +360,7 @@ nsImageControlFrame::MouseClicked(nsIPresContext* aPresContext)
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
if (nsnull != formContent) {
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
formContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}
if (nsEventStatus_eConsumeNoDefault != status) {

View File

@ -1437,3 +1437,4 @@ nsresult nsListControlFrame::RequiresWidget(PRBool& aRequiresWidget)
}

View File

@ -89,7 +89,7 @@ public:
/*virtual nsresult Focus(nsIDOMEvent* aEvent);
virtual nsresult Blur(nsIDOMEvent* aEvent);
virtual nsresult ProcessEvent(nsIDOMEvent* aEvent);
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
NS_IMETHOD AddEventListener(nsIDOMNode * aNode);
NS_IMETHOD RemoveEventListener(nsIDOMNode * aNode);

View File

@ -1080,7 +1080,7 @@ nsSelectControlFrame::MouseClicked(nsIPresContext* aPresContext)
event.message = NS_FORM_CHANGE;
if (nsnull != mContent) {
mContent->HandleDOMEvent(*aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
mContent->HandleDOMEvent(*aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
}

View File

@ -218,7 +218,7 @@ nsTextControlFrame::EnterPressed(nsIPresContext& aPresContext)
event.eventStructType = NS_EVENT;
event.message = NS_FORM_SUBMIT;
formContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status);
formContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
NS_RELEASE(formContent);
}

View File

@ -1050,7 +1050,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
// first-child, lang, active, focus, hover, link, outOfDate, visited
// XXX disabled, enabled, selected, selection
nsAtomList* pseudoClass = aSelector->mPseudoClassList;
nsLinkEventState eventState = eLinkState_Unspecified;
PRInt32 eventState = NS_EVENT_STATE_UNSPECIFIED;
nsLinkState linkState = nsLinkState(-1); // not a link
nsILinkHandler* linkHandler = nsnull;
nsIEventStateManager* eventStateManager = nsnull;
@ -1092,18 +1092,17 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
if (! eventStateManager) {
aPresContext->GetEventStateManager(&eventStateManager);
if (eventStateManager) {
eventStateManager->GetLinkState(aContent, eventState);
eventStateManager->GetContentState(aContent, eventState);
}
}
if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) {
result = PRBool(0 != (eventState & eLinkState_Active));
result = PRBool(0 != (eventState & NS_EVENT_STATE_ACTIVE));
}
else if (nsCSSAtoms::focusPseudo == pseudoClass->mAtom) {
// result = PRBool(0 != (eventState & eLinkState_Focus));
result = PR_FALSE;
result = PRBool(0 != (eventState & NS_EVENT_STATE_FOCUS));
}
else if (nsCSSAtoms::hoverPseudo == pseudoClass->mAtom) {
result = PRBool(0 != (eventState & eLinkState_Hover));
result = PRBool(0 != (eventState & NS_EVENT_STATE_HOVER));
}
}
else if (IsLinkPseudo(pseudoClass->mAtom)) {

View File

@ -468,9 +468,9 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
(nsnull != eventStateManager)) {
nsLinkEventState state;
if (NS_OK == eventStateManager->GetLinkState(aContent, state)) {
if (0 != (state & eLinkState_Active)) {
PRInt32 state;
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
aResults->AppendElement(mActiveRule);
matchCount++;
}

View File

@ -1050,7 +1050,7 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
// first-child, lang, active, focus, hover, link, outOfDate, visited
// XXX disabled, enabled, selected, selection
nsAtomList* pseudoClass = aSelector->mPseudoClassList;
nsLinkEventState eventState = eLinkState_Unspecified;
PRInt32 eventState = NS_EVENT_STATE_UNSPECIFIED;
nsLinkState linkState = nsLinkState(-1); // not a link
nsILinkHandler* linkHandler = nsnull;
nsIEventStateManager* eventStateManager = nsnull;
@ -1092,18 +1092,17 @@ static PRBool SelectorMatches(nsIPresContext* aPresContext,
if (! eventStateManager) {
aPresContext->GetEventStateManager(&eventStateManager);
if (eventStateManager) {
eventStateManager->GetLinkState(aContent, eventState);
eventStateManager->GetContentState(aContent, eventState);
}
}
if (nsCSSAtoms::activePseudo == pseudoClass->mAtom) {
result = PRBool(0 != (eventState & eLinkState_Active));
result = PRBool(0 != (eventState & NS_EVENT_STATE_ACTIVE));
}
else if (nsCSSAtoms::focusPseudo == pseudoClass->mAtom) {
// result = PRBool(0 != (eventState & eLinkState_Focus));
result = PR_FALSE;
result = PRBool(0 != (eventState & NS_EVENT_STATE_FOCUS));
}
else if (nsCSSAtoms::hoverPseudo == pseudoClass->mAtom) {
result = PRBool(0 != (eventState & eLinkState_Hover));
result = PRBool(0 != (eventState & NS_EVENT_STATE_HOVER));
}
}
else if (IsLinkPseudo(pseudoClass->mAtom)) {

View File

@ -468,9 +468,9 @@ PRInt32 HTMLStyleSheetImpl::RulesMatching(nsIPresContext* aPresContext,
if ((NS_OK == aPresContext->GetEventStateManager(&eventStateManager)) &&
(nsnull != eventStateManager)) {
nsLinkEventState state;
if (NS_OK == eventStateManager->GetLinkState(aContent, state)) {
if (0 != (state & eLinkState_Active)) {
PRInt32 state;
if (NS_OK == eventStateManager->GetContentState(aContent, state)) {
if (0 != (state & NS_EVENT_STATE_ACTIVE)) {
aResults->AppendElement(mActiveRule);
matchCount++;
}

View File

@ -136,45 +136,36 @@ nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
{
nsIEventStateManager *stateManager;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->SetActiveLink(this);
stateManager->SetActiveContent(this);
NS_RELEASE(stateManager);
}
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
break;
case NS_MOUSE_LEFT_BUTTON_UP:
case NS_MOUSE_LEFT_CLICK:
{
nsIEventStateManager *stateManager;
nsLinkEventState linkState;
if (NS_OK == aPresContext.GetEventStateManager(&stateManager)) {
stateManager->GetLinkState(this, linkState);
NS_RELEASE(stateManager);
}
if (eLinkState_Active == linkState) {
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString show, href, target;
nsIURL* baseURL = nsnull;
nsLinkVerb verb = eLinkVerb_Replace;
target.Truncate();
GetAttribute(kNameSpaceID_None, kHrefAtom, href);
GetAttribute(kNameSpaceID_None, kShowAtom, show);
// XXX Should probably do this using atoms
if (show.Equals("new")) {
verb = eLinkVerb_New;
}
else if (show.Equals("embed")) {
verb = eLinkVerb_Embed;
}
if (nsnull != mInner.mDocument) {
baseURL = mInner.mDocument->GetDocumentURL();
}
mInner.TriggerLink(aPresContext, verb, baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
if (nsEventStatus_eConsumeNoDefault != aEventStatus) {
nsAutoString show, href, target;
nsIURL* baseURL = nsnull;
nsLinkVerb verb = eLinkVerb_Replace;
target.Truncate();
GetAttribute(kNameSpaceID_None, kHrefAtom, href);
GetAttribute(kNameSpaceID_None, kShowAtom, show);
// XXX Should probably do this using atoms
if (show.Equals("new")) {
verb = eLinkVerb_New;
}
else if (show.Equals("embed")) {
verb = eLinkVerb_Embed;
}
if (nsnull != mInner.mDocument) {
baseURL = mInner.mDocument->GetDocumentURL();
}
mInner.TriggerLink(aPresContext, verb, baseURL, href, target, PR_TRUE);
NS_IF_RELEASE(baseURL);
aEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
break;
@ -184,7 +175,6 @@ nsXMLElement::HandleDOMEvent(nsIPresContext& aPresContext,
break;
case NS_MOUSE_ENTER:
//mouse enter doesn't work yet. Use move until then.
{
nsAutoString href, target;
nsIURL* baseURL = nsnull;