diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index 09942d3abbcf..177220ec8c8b 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -155,9 +155,10 @@ public: NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const = 0; NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) = 0; + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) = 0; }; #endif /* nsIContent_h___ */ diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index 349f9583747f..ba329ca95d75 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -224,9 +224,10 @@ public: virtual nsIContent* GetNextContent(nsIContent *aContent) const = 0; NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) = 0; + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) = 0; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 7e65850c2c6d..01254683aec2 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -30,6 +30,9 @@ #include "nsIScriptGlobalObject.h" #include "nsIScriptContextOwner.h" #include "nsIParser.h" +#include "nsDOMEvent.h" +#include "nsIPrivateDOMEvent.h" +#include "nsIEventStateManager.h" #include "nsContentList.h" #include "nsCSSPropIDs.h" @@ -57,6 +60,7 @@ static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID); static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); +static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIPostDataIID, NS_IPOSTDATA_IID); static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); @@ -193,6 +197,7 @@ nsDocument::~nsDocument() NS_IF_RELEASE(mSelection); NS_IF_RELEASE(mScriptContextOwner); NS_IF_RELEASE(mParser); + NS_IF_RELEASE(mListenerManager); } nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) @@ -848,6 +853,7 @@ nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrRe if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) { mListenerManager = l; + NS_ADDREF(mListenerManager); return NS_OK; } @@ -856,10 +862,24 @@ nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrRe } nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) { + nsresult mRet = NS_OK; + + if (DOM_EVENT_INIT == aFlags) { + nsIEventStateManager *mManager; + if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { + mManager->SetEventTarget((nsIDocument*)this); + NS_RELEASE(mManager); + } + + nsIDOMEvent* mDOMEvent = nsnull; + aDOMEvent = &mDOMEvent; + } + //Capturing stage //Local handling stage @@ -870,15 +890,31 @@ nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext, //Bubbling stage /*Need to go to window here*/ - return NS_OK; + if (DOM_EVENT_INIT == aFlags) { + // We're leaving the DOM event loop so if we created a DOM event, release here. + if (nsnull != *aDOMEvent) { + if (0 != (*aDOMEvent)->Release()) { + //Okay, so someone in the DOM loop (a listener, JS object) still has a ref to the DOM Event but + //the internal data hasn't been malloc'd. Force a copy of the data here so the DOM Event is still valid. + nsIPrivateDOMEvent *mPrivateEvent; + if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&mPrivateEvent)) { + mPrivateEvent->DuplicatePrivateData(); + NS_RELEASE(mPrivateEvent); + } + } + } + } + + return mRet; } nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - nsIEventListenerManager *manager; + nsIEventListenerManager *mManager; - if (NS_OK == GetListenerManager(&manager)) { - manager->AddEventListener(aListener, aIID); + if (NS_OK == GetListenerManager(&mManager)) { + mManager->AddEventListener(aListener, aIID); + NS_RELEASE(mManager); return NS_OK; } return NS_ERROR_FAILURE; @@ -886,10 +922,8 @@ nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsII nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - nsIEventListenerManager *manager; - - if (NS_OK == GetListenerManager(&manager)) { - manager->RemoveEventListener(aListener, aIID); + if (nsnull != mListenerManager) { + mListenerManager->RemoveEventListener(aListener, aIID); return NS_OK; } return NS_ERROR_FAILURE; @@ -897,10 +931,11 @@ nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const n nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener) { - nsIEventListenerManager *manager; + nsIEventListenerManager *mManager; - if (NS_OK == GetListenerManager(&manager)) { - manager->CaptureEvent(aListener); + if (NS_OK == GetListenerManager(&mManager)) { + mManager->CaptureEvent(aListener); + NS_RELEASE(mManager); return NS_OK; } return NS_ERROR_FAILURE; @@ -908,17 +943,13 @@ nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener) nsresult nsDocument::ReleaseEvent(nsIDOMEventListener *aListener) { - nsIEventListenerManager *manager; - - if (NS_OK == GetListenerManager(&manager)) { - manager->ReleaseEvent(aListener); + if (nsnull != mListenerManager) { + mListenerManager->ReleaseEvent(aListener); return NS_OK; } return NS_ERROR_FAILURE; } - - /** * Returns the Selection Object */ diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 141fb7247662..23444122a849 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -246,8 +246,9 @@ public: NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult); NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, nsEventStatus& aEventStatus); diff --git a/content/events/public/makefile.win b/content/events/public/makefile.win index c1fcc7bbb8d6..51c3e4d81d9c 100644 --- a/content/events/public/makefile.win +++ b/content/events/public/makefile.win @@ -21,6 +21,7 @@ IGNORE_MANIFEST=1 EXPORTS = \ nsIEventListenerManager.h \ nsIEventStateManager.h \ + nsIPrivateDOMEvent.h \ $(NULL) MODULE=raptor diff --git a/content/events/public/nsIEventListenerManager.h b/content/events/public/nsIEventListenerManager.h index 295e079287f8..c5a325dc2357 100644 --- a/content/events/public/nsIEventListenerManager.h +++ b/content/events/public/nsIEventListenerManager.h @@ -66,9 +66,9 @@ public: */ virtual nsresult HandleEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) = 0; + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + nsEventStatus& aEventStatus) = 0; /** * Captures all events designated for descendant objects at the current level. diff --git a/content/events/public/nsIEventStateManager.h b/content/events/public/nsIEventStateManager.h index cb6d57e54c1c..24c440b4c7da 100644 --- a/content/events/public/nsIEventStateManager.h +++ b/content/events/public/nsIEventStateManager.h @@ -32,9 +32,9 @@ class nsIDOMEvent; * Event listener manager interface. */ #define NS_IEVENTSTATEMANAGER_IID \ -{ /* c8488290-07ce-11d2-bd88-00805f8ae3f4 */ \ -0xc8488290, 0x07ce, 0x11d2, \ -{0xbd, 0x88, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } +{ /* 80a98c80-2036-11d2-bd89-00805f8ae3f4 */ \ +0x80a98c80, 0x2036, 0x11d2, \ +{0xbd, 0x89, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } class nsIEventStateManager : public nsISupports { diff --git a/content/events/public/nsIPrivateDOMEvent.h b/content/events/public/nsIPrivateDOMEvent.h new file mode 100644 index 000000000000..185981de46d0 --- /dev/null +++ b/content/events/public/nsIPrivateDOMEvent.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIPrivateDOMEvent_h__ +#define nsIPrivateDOMEvent_h__ + +#include "nsGUIEvent.h" +#include "nsISupports.h" + +class nsIPresContext; + +/* + * Event listener manager interface. + */ +#define NS_IPRIVATEDOMEVENT_IID \ +{ /* 80a98c80-2036-11d2-bd89-00805f8ae3f4 */ \ +0x80a98c80, 0x2036, 0x11d2, \ +{0xbd, 0x89, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } + +class nsIPrivateDOMEvent : public nsISupports { + +public: + NS_IMETHOD DuplicatePrivateData() = 0; +}; + +extern nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsIPresContext& aPresContext, nsEvent *aEvent); + +#endif // nsIPrivateDOMEvent_h__ diff --git a/content/events/src/makefile.win b/content/events/src/makefile.win index 111651d3103e..fb627926014f 100644 --- a/content/events/src/makefile.win +++ b/content/events/src/makefile.win @@ -37,7 +37,7 @@ CPP_OBJS= .\$(OBJDIR)\nsEventListenerManager.obj \ $(NULL) -EXPORTS= nsEventListenerManager.h nsEventStateManager.h +EXPORTS= nsEventListenerManager.h nsEventStateManager.h nsDOMEvent.h LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \ -I$(PUBLIC)\dom -I$(PUBLIC)\js diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index 8350b106f766..8d4828953e30 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -18,17 +18,12 @@ #include "nsDOMEvent.h" #include "nsIDOMNode.h" +#include "nsIEventStateManager.h" static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIDOMEventIID, NS_IDOMEVENT_IID); static NS_DEFINE_IID(kIDOMNSEventIID, NS_IDOMNSEVENT_IID); - - -enum mEventEnum { - onmousedown=0, onmouseup=1, onclick=2, ondblclick=3, onmouseover=4, onmouseout=5, - onmousemove=6, onkeydown=7, onkeyup=8, onkeypress=9, onfocus=10, onblur=11, - onload=12, onabort=13, onerror=14 -}; +static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static char* mEventNames[] = { "onmousedown", "onmouseup", "onclick", "ondblclick", "onmouseover", "onmouseout", @@ -36,13 +31,15 @@ static char* mEventNames[] = { "onload", "onabort", "onerror" }; -nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext) { - kPresContext = aPresContext; - NS_ADDREF(kPresContext); +nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent) { + mPresContext = aPresContext; + NS_ADDREF(mPresContext); + mEvent = aEvent; + NS_INIT_REFCNT(); } nsDOMEvent::~nsDOMEvent() { - NS_RELEASE(kPresContext); + NS_RELEASE(mPresContext); } NS_IMPL_ADDREF(nsDOMEvent) @@ -65,13 +62,18 @@ nsresult nsDOMEvent::QueryInterface(const nsIID& aIID, AddRef(); return NS_OK; } + if (aIID.Equals(kIPrivateDOMEventIID)) { + *aInstancePtrResult = (void*) ((nsIPrivateDOMEvent*)this); + AddRef(); + return NS_OK; + } return NS_NOINTERFACE; } // nsIDOMEventInterface NS_METHOD nsDOMEvent::GetType(nsString& aType) { - const char* mName = GetEventName(kEvent->message); + const char* mName = GetEventName(mEvent->message); if (nsnull != mName) { aType = nsString(mName); @@ -88,7 +90,15 @@ NS_METHOD nsDOMEvent::SetType(const nsString& aType) NS_METHOD nsDOMEvent::GetTarget(nsIDOMNode** aTarget) { - return kTarget->QueryInterface(kIDOMNodeIID, (void**)aTarget); + nsIEventStateManager *mManager; + nsISupports *mTarget; + + if (NS_OK == mPresContext->GetEventStateManager(&mManager)) { + mManager->GetEventTarget(&mTarget); + NS_RELEASE(mManager); + } + + return mTarget->QueryInterface(kIDOMNodeIID, (void**)aTarget); } NS_METHOD nsDOMEvent::SetTarget(nsIDOMNode* aTarget) @@ -118,7 +128,7 @@ NS_METHOD nsDOMEvent::SetScreenY(PRInt32 aScreenY) NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX) { - *aClientX = NS_TO_INT_ROUND(kEvent->point.x * kPresContext->GetTwipsToPixels()); + *aClientX = NS_TO_INT_ROUND(mEvent->point.x * mPresContext->GetTwipsToPixels()); return NS_OK; } @@ -129,7 +139,7 @@ NS_METHOD nsDOMEvent::SetClientX(PRInt32 aClientX) NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY) { - *aClientY = NS_TO_INT_ROUND(kEvent->point.y * kPresContext->GetTwipsToPixels()); + *aClientY = NS_TO_INT_ROUND(mEvent->point.y * mPresContext->GetTwipsToPixels()); return NS_OK; } @@ -140,7 +150,7 @@ NS_METHOD nsDOMEvent::SetClientY(PRInt32 aClientY) NS_METHOD nsDOMEvent::GetAltKey(PRBool* aIsDown) { - *aIsDown = ((nsInputEvent*)kEvent)->isAlt; + *aIsDown = ((nsInputEvent*)mEvent)->isAlt; return NS_OK; } @@ -151,7 +161,7 @@ NS_METHOD nsDOMEvent::SetAltKey(PRBool aAltKey) NS_METHOD nsDOMEvent::GetCtrlKey(PRBool* aIsDown) { - *aIsDown = ((nsInputEvent*)kEvent)->isControl; + *aIsDown = ((nsInputEvent*)mEvent)->isControl; return NS_OK; } @@ -162,7 +172,7 @@ NS_METHOD nsDOMEvent::SetCtrlKey(PRBool aCtrlKey) NS_METHOD nsDOMEvent::GetShiftKey(PRBool* aIsDown) { - *aIsDown = ((nsInputEvent*)kEvent)->isShift; + *aIsDown = ((nsInputEvent*)mEvent)->isShift; return NS_OK; } @@ -193,10 +203,10 @@ NS_METHOD nsDOMEvent::SetCharCode(PRUint32 aCharCode) NS_METHOD nsDOMEvent::GetKeyCode(PRUint32* aKeyCode) { - switch (kEvent->message) { + switch (mEvent->message) { case NS_KEY_UP: case NS_KEY_DOWN: - *aKeyCode = ((nsKeyEvent*)kEvent)->keyCode; + *aKeyCode = ((nsKeyEvent*)mEvent)->keyCode; break; default: return NS_ERROR_FAILURE; @@ -211,7 +221,7 @@ NS_METHOD nsDOMEvent::SetKeyCode(PRUint32 aKeyCode) NS_METHOD nsDOMEvent::GetButton(PRUint32* aButton) { - switch (kEvent->message) { + switch (mEvent->message) { case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_LEFT_DOUBLECLICK: @@ -258,15 +268,9 @@ NS_METHOD nsDOMEvent::SetLayerY(PRInt32 aLayerY) return NS_ERROR_NOT_IMPLEMENTED; } -NS_METHOD nsDOMEvent::SetGUIEvent(nsGUIEvent *aEvent) +NS_METHOD nsDOMEvent::DuplicatePrivateData() { - kEvent = aEvent; - return NS_OK; -} - -NS_METHOD nsDOMEvent::SetEventTarget(nsISupports *aTarget) -{ - kTarget = aTarget; + //XXX Write me! return NS_OK; } @@ -276,34 +280,44 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType) case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: - return mEventNames[onmousedown]; + return mEventNames[eDOMEvents_mousedown]; break; case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: - return mEventNames[onmouseup]; + return mEventNames[eDOMEvents_mouseup]; break; case NS_MOUSE_LEFT_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK: - return mEventNames[ondblclick]; + return mEventNames[eDOMEvents_dblclick]; break; - /*case NS_MOUSE_ENTER: - return mEventNames[onmouseover]; + case NS_MOUSE_ENTER: + return mEventNames[eDOMEvents_mouseover]; break; case NS_MOUSE_EXIT: - return mEventNames[onmouseout]; - break;*/ + return mEventNames[eDOMEvents_mouseout]; + break; case NS_MOUSE_MOVE: - return mEventNames[onmousemove]; + return mEventNames[eDOMEvents_mousemove]; break; case NS_KEY_UP: - return mEventNames[onkeyup]; + return mEventNames[eDOMEvents_keyup]; break; case NS_KEY_DOWN: - return mEventNames[onkeydown]; + return mEventNames[eDOMEvents_keydown]; break; default: break; } return nsnull; } + +nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsIPresContext& aPresContext, nsEvent *aEvent) +{ + nsDOMEvent* it = new nsDOMEvent(&aPresContext, aEvent); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return it->QueryInterface(kIDOMEventIID, (void **) aInstancePtrResult); +} diff --git a/content/events/src/nsDOMEvent.h b/content/events/src/nsDOMEvent.h index 2f1847ee3f43..8ed450596642 100644 --- a/content/events/src/nsDOMEvent.h +++ b/content/events/src/nsDOMEvent.h @@ -21,22 +21,27 @@ #include "nsIDOMEvent.h" #include "nsISupports.h" +#include "nsIPrivateDOMEvent.h" + #include "nsIPresContext.h" #include "nsPoint.h" #include "nsGUIEvent.h" class nsIContent; -class nsDOMEvent : public nsIDOMEvent, public nsIDOMNSEvent { +class nsDOMEvent : public nsIDOMEvent, public nsIDOMNSEvent, public nsIPrivateDOMEvent { + +#define DOM_EVENT_INIT 0x0001 +#define DOM_EVENT_BUBBLE 0x0002 +#define DOM_EVENT_CAPTURE 0x0004 public: - - enum nsEventStatus { - nsEventStatus_eIgnore, // The event is ignored, do default processing - nsEventStatus_eConsumeNoDefault, // The event is consumed, don't do default processing - nsEventStatus_eConsumeDoDefault // The event is consumed, but do default processing + enum nsDOMEvents { + eDOMEvents_mousedown=0, eDOMEvents_mouseup=1, eDOMEvents_click=2, eDOMEvents_dblclick=3, eDOMEvents_mouseover=4, eDOMEvents_mouseout=5, + eDOMEvents_mousemove=6, eDOMEvents_keydown=7, eDOMEvents_keyup=8, eDOMEvents_keypress=9, eDOMEvents_focus=10, eDOMEvents_blur=11, + eDOMEvents_load=12, eDOMEvents_abort=13, eDOMEvents_error=14 }; - nsDOMEvent(nsIPresContext* aPresContext); + nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent); virtual ~nsDOMEvent(); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); @@ -83,25 +88,24 @@ public: NS_IMETHOD GetButton(PRUint32* aButton); NS_IMETHOD SetButton(PRUint32 aButton); - // nsINSEventInterface + // nsIDOMNSEvent interface NS_IMETHOD GetLayerX(PRInt32* aLayerX); NS_IMETHOD SetLayerX(PRInt32 aLayerX); NS_IMETHOD GetLayerY(PRInt32* aLayerY); NS_IMETHOD SetLayerY(PRInt32 aLayerY); - // Local functions - NS_IMETHOD SetGUIEvent(nsGUIEvent *aEvent); - NS_IMETHOD SetEventTarget(nsISupports *aTarget); + // nsIPrivateDOMEvent interface + NS_IMETHOD DuplicatePrivateData(); protected: PRUint32 mRefCnt : 31; - nsGUIEvent *kEvent; - nsISupports *kTarget; - nsIPresContext *kPresContext; + nsEvent *mEvent; + nsIPresContext *mPresContext; const char* GetEventName(PRUint32 aEventType); }; + #endif // nsDOMEvent_h__ diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index 7556d31bc5fc..4788d06f820b 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -29,6 +29,7 @@ #include "nsIDOMLoadListener.h" #include "nsIDOMDragListener.h" #include "nsIEventStateManager.h" +#include "nsIPrivateDOMEvent.h" static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID); @@ -40,7 +41,8 @@ static NS_DEFINE_IID(kIDOMLoadListenerIID, NS_IDOMLOADLISTENER_IID); static NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID); static NS_DEFINE_IID(kIDOMEventIID, NS_IDOMEVENT_IID); -nsEventListenerManager::nsEventListenerManager() { +nsEventListenerManager::nsEventListenerManager() +{ mEventListeners = nsnull; mMouseListeners = nsnull; mMouseMotionListeners = nsnull; @@ -48,9 +50,18 @@ nsEventListenerManager::nsEventListenerManager() { mLoadListeners = nsnull; mFocusListeners = nsnull; mDragListeners = nsnull; + NS_INIT_REFCNT(); } -nsEventListenerManager::~nsEventListenerManager() { +nsEventListenerManager::~nsEventListenerManager() +{ + ReleaseListeners(mEventListeners); + ReleaseListeners(mMouseListeners); + ReleaseListeners(mMouseMotionListeners); + ReleaseListeners(mKeyListeners); + ReleaseListeners(mLoadListeners); + ReleaseListeners(mFocusListeners); + ReleaseListeners(mDragListeners); } NS_IMPL_ADDREF(nsEventListenerManager) @@ -71,48 +82,49 @@ nsresult nsEventListenerManager::QueryInterface(const nsIID& aIID, return NS_NOINTERFACE; } -nsresult nsEventListenerManager::TranslateGUI2DOM(nsGUIEvent*& aGUIEvent, - nsIPresContext& aPresContext, - nsIDOMEvent** aDOMEvent) +nsVoidArray** nsEventListenerManager::GetListenersByIID(const nsIID& aIID) { - nsIEventStateManager *mManager; - nsISupports *mTarget; - - nsDOMEvent* it = new nsDOMEvent(&aPresContext); - if (nsnull == it) { - return NS_ERROR_OUT_OF_MEMORY; + if (aIID.Equals(kIDOMMouseListenerIID)) { + return &mMouseListeners; } - - it->SetGUIEvent(aGUIEvent); - if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { - mManager->GetEventTarget(&mTarget); - NS_RELEASE(mManager); + else if (aIID.Equals(kIDOMMouseMotionListenerIID)) { + return &mMouseMotionListeners; } - it->SetEventTarget(mTarget); + else if (aIID.Equals(kIDOMKeyListenerIID)) { + return &mKeyListeners; + } + else if (aIID.Equals(kIDOMLoadListenerIID)) { + return &mLoadListeners; + } + else if (aIID.Equals(kIDOMFocusListenerIID)) { + return &mFocusListeners; + } + else if (aIID.Equals(kIDOMDragListenerIID)) { + return &mDragListeners; + } + return nsnull; +} - return it->QueryInterface(kIDOMEventIID, (void **) aDOMEvent); +void nsEventListenerManager::ReleaseListeners(nsVoidArray* aListeners) +{ + if (nsnull != aListeners) { + PRInt32 i, count = aListeners->Count(); + nsIDOMEventListener *mElement; + for (i = 0; i < count; i++) { + mElement = (nsIDOMEventListener *)aListeners->ElementAt(i); + if (mElement != nsnull) { + NS_RELEASE(mElement); + } + } + delete aListeners; + } } nsresult nsEventListenerManager::GetEventListeners(nsVoidArray **aListeners, const nsIID& aIID) { - if (aIID.Equals(kIDOMMouseListenerIID)) { - *aListeners = mMouseListeners; - } - if (aIID.Equals(kIDOMMouseMotionListenerIID)) { - *aListeners = mMouseMotionListeners; - } - if (aIID.Equals(kIDOMKeyListenerIID)) { - *aListeners = mKeyListeners; - } - if (aIID.Equals(kIDOMLoadListenerIID)) { - *aListeners = mLoadListeners; - } - if (aIID.Equals(kIDOMFocusListenerIID)) { - *aListeners = mFocusListeners; - } - if (aIID.Equals(kIDOMDragListenerIID)) { - *aListeners = mDragListeners; - } + nsVoidArray** mListeners = GetListenersByIID(aIID); + + *aListeners = *mListeners; return NS_OK; } @@ -124,42 +136,20 @@ nsresult nsEventListenerManager::GetEventListeners(nsVoidArray **aListeners, con nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - if (aIID.Equals(kIDOMMouseListenerIID)) { - if (nsnull == mMouseListeners) { - mMouseListeners = new nsVoidArray(); - mMouseListeners->InsertElementAt((void*)aListener, mMouseListeners->Count()); - } + nsVoidArray** mListeners = GetListenersByIID(aIID); + + if (nsnull == *mListeners) { + *mListeners = new nsVoidArray(); } - if (aIID.Equals(kIDOMMouseMotionListenerIID)) { - if (nsnull == mMouseMotionListeners) { - mMouseMotionListeners = new nsVoidArray(); - mMouseMotionListeners->InsertElementAt((void*)aListener, mMouseMotionListeners->Count()); - } - } - if (aIID.Equals(kIDOMKeyListenerIID)) { - if (nsnull == mKeyListeners) { - mKeyListeners = new nsVoidArray(); - mKeyListeners->InsertElementAt((void*)aListener, mKeyListeners->Count()); - } - } - if (aIID.Equals(kIDOMLoadListenerIID)) { - if (nsnull == mLoadListeners) { - mLoadListeners = new nsVoidArray(); - mLoadListeners->InsertElementAt((void*)aListener, mLoadListeners->Count()); - } - } - if (aIID.Equals(kIDOMFocusListenerIID)) { - if (nsnull == mFocusListeners) { - mFocusListeners = new nsVoidArray(); - mFocusListeners->InsertElementAt((void*)aListener, mFocusListeners->Count()); - } - } - if (aIID.Equals(kIDOMDragListenerIID)) { - if (nsnull == mDragListeners) { - mDragListeners = new nsVoidArray(); - mDragListeners->InsertElementAt((void*)aListener, mDragListeners->Count()); - } + + if (nsnull == *mListeners) { + return NS_ERROR_OUT_OF_MEMORY; } + + (*mListeners)->InsertElementAt((void*)aListener, (*mListeners)->Count()); + + NS_ADDREF(aListener); + return NS_OK; } @@ -170,43 +160,13 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - if (aIID.Equals(kIDOMMouseListenerIID)) { - if (nsnull == mMouseListeners) { - mMouseListeners = new nsVoidArray(); - mMouseListeners->RemoveElement((void*)aListener); - } + nsVoidArray** mListeners = GetListenersByIID(aIID); + + if (nsnull != *mListeners && PR_TRUE == (*mListeners)->RemoveElement((void*)aListener)) { + NS_RELEASE(aListener); + return NS_OK; } - if (aIID.Equals(kIDOMMouseMotionListenerIID)) { - if (nsnull == mMouseMotionListeners) { - mMouseMotionListeners = new nsVoidArray(); - mMouseMotionListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMKeyListenerIID)) { - if (nsnull == mKeyListeners) { - mKeyListeners = new nsVoidArray(); - mKeyListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMLoadListenerIID)) { - if (nsnull == mLoadListeners) { - mLoadListeners = new nsVoidArray(); - mLoadListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMFocusListenerIID)) { - if (nsnull == mFocusListeners) { - mFocusListeners = new nsVoidArray(); - mFocusListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMDragListenerIID)) { - if (nsnull == mDragListeners) { - mDragListeners = new nsVoidArray(); - mDragListeners->RemoveElement((void*)aListener); - } - } - return NS_OK; + return NS_ERROR_FAILURE; } /** @@ -215,9 +175,9 @@ nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListe */ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + nsEventStatus& aEventStatus) { nsresult mRet = NS_OK; @@ -233,10 +193,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_MOUSE_ENTER: case NS_MOUSE_EXIT: if (nsnull != mMouseListeners) { - if (nsnull == aDOMEvent) { - TranslateGUI2DOM(aEvent, aPresContext, &aDOMEvent); + if (nsnull == *aDOMEvent) { + mRet = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent); } - if (nsnull != aDOMEvent) { + if (NS_OK == mRet) { for (int i=0; iCount(); i++) { nsIDOMEventListener *mEventListener; nsIDOMMouseListener *mMouseListener; @@ -248,22 +208,22 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: - mRet = mMouseListener->MouseDown(aDOMEvent); + mRet = mMouseListener->MouseDown(*aDOMEvent); break; case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: - mRet = mMouseListener->MouseUp(aDOMEvent); + mRet = mMouseListener->MouseUp(*aDOMEvent); break; case NS_MOUSE_LEFT_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK: - mRet = mMouseListener->MouseDblClick(aDOMEvent); + mRet = mMouseListener->MouseDblClick(*aDOMEvent); break; case NS_MOUSE_ENTER: - mRet = mMouseListener->MouseOver(aDOMEvent); + mRet = mMouseListener->MouseOver(*aDOMEvent); break; case NS_MOUSE_EXIT: - mRet = mMouseListener->MouseOut(aDOMEvent); + mRet = mMouseListener->MouseOut(*aDOMEvent); break; default: break; @@ -271,7 +231,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, NS_RELEASE(mMouseListener); } else { - mRet = mEventListener->ProcessEvent(aDOMEvent); + mRet = mEventListener->ProcessEvent(*aDOMEvent); } aEventStatus = (NS_OK == mRet) ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault; } @@ -281,10 +241,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_MOUSE_MOVE: if (nsnull != mMouseMotionListeners) { - if (nsnull == aDOMEvent) { - TranslateGUI2DOM(aEvent, aPresContext, &aDOMEvent); + if (nsnull == *aDOMEvent) { + mRet = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent); } - if (nsnull != aDOMEvent) { + if (NS_OK == mRet) { for (int i=0; iCount(); i++) { nsIDOMEventListener *mEventListener; nsIDOMMouseMotionListener *mMouseMotionListener; @@ -294,7 +254,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, if (NS_OK == mEventListener->QueryInterface(kIDOMMouseMotionListenerIID, (void**)&mMouseMotionListener)) { switch(aEvent->message) { case NS_MOUSE_MOVE: - mRet = mMouseMotionListener->MouseMove(aDOMEvent); + mRet = mMouseMotionListener->MouseMove(*aDOMEvent); break; default: break; @@ -302,7 +262,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, NS_RELEASE(mMouseMotionListener); } else { - mRet = mEventListener->ProcessEvent(aDOMEvent); + mRet = mEventListener->ProcessEvent(*aDOMEvent); } aEventStatus = (NS_OK == mRet) ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault; } @@ -313,10 +273,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_KEY_UP: case NS_KEY_DOWN: if (nsnull != mKeyListeners) { - if (nsnull == aDOMEvent) { - TranslateGUI2DOM(aEvent, aPresContext, &aDOMEvent); + if (nsnull == *aDOMEvent) { + mRet = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent); } - if (nsnull != aDOMEvent) { + if (NS_OK == mRet) { for (int i=0; iCount(); i++) { nsIDOMEventListener *mEventListener; nsIDOMKeyListener *mKeyListener; @@ -326,10 +286,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, if (NS_OK == mEventListener->QueryInterface(kIDOMKeyListenerIID, (void**)&mKeyListener)) { switch(aEvent->message) { case NS_KEY_UP: - mRet = mKeyListener->KeyUp(aDOMEvent); + mRet = mKeyListener->KeyUp(*aDOMEvent); break; case NS_KEY_DOWN: - mRet = mKeyListener->KeyDown(aDOMEvent); + mRet = mKeyListener->KeyDown(*aDOMEvent); break; default: break; @@ -337,7 +297,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, NS_RELEASE(mKeyListener); } else { - mRet = mEventListener->ProcessEvent(aDOMEvent); + mRet = mEventListener->ProcessEvent(*aDOMEvent); } aEventStatus = (NS_OK == mRet) ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault; } diff --git a/content/events/src/nsEventListenerManager.h b/content/events/src/nsEventListenerManager.h index a650bda9103b..f0371d30a0f3 100644 --- a/content/events/src/nsEventListenerManager.h +++ b/content/events/src/nsEventListenerManager.h @@ -36,6 +36,10 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + nsVoidArray** GetListenersByIID(const nsIID& aIID); + + void ReleaseListeners(nsVoidArray* aListeners); + /** * Retrieves events listeners of all types. * @param @@ -55,16 +59,12 @@ public: virtual nsresult CaptureEvent(nsIDOMEventListener *aListener); virtual nsresult ReleaseEvent(nsIDOMEventListener *aListener); - virtual nsresult HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsIDOMEvent* aDOMEvent, nsEventStatus& aEventStatus); + virtual nsresult HandleEvent(nsIPresContext& aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, nsEventStatus& aEventStatus); protected: PRUint32 mRefCnt : 31; - virtual nsresult TranslateGUI2DOM(nsGUIEvent*& aGUIEvent, - nsIPresContext& aPresContext, - nsIDOMEvent** aDOMEvent); - nsVoidArray* mEventListeners; nsVoidArray* mMouseListeners; nsVoidArray* mMouseMotionListeners; diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index f68dacbc6dd2..bbbf0707a03c 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -74,7 +74,7 @@ NS_METHOD nsEventStateManager::SetLastMouseOverContent(nsIContent *aContent) NS_IF_RELEASE(mLastMouseOverContent); mLastMouseOverContent = aContent; - NS_ADDREF(mLastMouseOverContent); + NS_IF_ADDREF(mLastMouseOverContent); return NS_OK; } diff --git a/layout/base/public/nsIContent.h b/layout/base/public/nsIContent.h index 09942d3abbcf..177220ec8c8b 100644 --- a/layout/base/public/nsIContent.h +++ b/layout/base/public/nsIContent.h @@ -155,9 +155,10 @@ public: NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const = 0; NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) = 0; + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) = 0; }; #endif /* nsIContent_h___ */ diff --git a/layout/base/public/nsIDocument.h b/layout/base/public/nsIDocument.h index 349f9583747f..ba329ca95d75 100644 --- a/layout/base/public/nsIDocument.h +++ b/layout/base/public/nsIDocument.h @@ -224,9 +224,10 @@ public: virtual nsIContent* GetNextContent(nsIContent *aContent) const = 0; NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) = 0; + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) = 0; diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index 7e65850c2c6d..01254683aec2 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -30,6 +30,9 @@ #include "nsIScriptGlobalObject.h" #include "nsIScriptContextOwner.h" #include "nsIParser.h" +#include "nsDOMEvent.h" +#include "nsIPrivateDOMEvent.h" +#include "nsIEventStateManager.h" #include "nsContentList.h" #include "nsCSSPropIDs.h" @@ -57,6 +60,7 @@ static NS_DEFINE_IID(kIDOMElementIID, NS_IDOMELEMENT_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); static NS_DEFINE_IID(kIDOMEventCapturerIID, NS_IDOMEVENTCAPTURER_IID); static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); +static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIPostDataIID, NS_IPOSTDATA_IID); static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID); @@ -193,6 +197,7 @@ nsDocument::~nsDocument() NS_IF_RELEASE(mSelection); NS_IF_RELEASE(mScriptContextOwner); NS_IF_RELEASE(mParser); + NS_IF_RELEASE(mListenerManager); } nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) @@ -848,6 +853,7 @@ nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrRe if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) { mListenerManager = l; + NS_ADDREF(mListenerManager); return NS_OK; } @@ -856,10 +862,24 @@ nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrRe } nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) { + nsresult mRet = NS_OK; + + if (DOM_EVENT_INIT == aFlags) { + nsIEventStateManager *mManager; + if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { + mManager->SetEventTarget((nsIDocument*)this); + NS_RELEASE(mManager); + } + + nsIDOMEvent* mDOMEvent = nsnull; + aDOMEvent = &mDOMEvent; + } + //Capturing stage //Local handling stage @@ -870,15 +890,31 @@ nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext, //Bubbling stage /*Need to go to window here*/ - return NS_OK; + if (DOM_EVENT_INIT == aFlags) { + // We're leaving the DOM event loop so if we created a DOM event, release here. + if (nsnull != *aDOMEvent) { + if (0 != (*aDOMEvent)->Release()) { + //Okay, so someone in the DOM loop (a listener, JS object) still has a ref to the DOM Event but + //the internal data hasn't been malloc'd. Force a copy of the data here so the DOM Event is still valid. + nsIPrivateDOMEvent *mPrivateEvent; + if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&mPrivateEvent)) { + mPrivateEvent->DuplicatePrivateData(); + NS_RELEASE(mPrivateEvent); + } + } + } + } + + return mRet; } nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - nsIEventListenerManager *manager; + nsIEventListenerManager *mManager; - if (NS_OK == GetListenerManager(&manager)) { - manager->AddEventListener(aListener, aIID); + if (NS_OK == GetListenerManager(&mManager)) { + mManager->AddEventListener(aListener, aIID); + NS_RELEASE(mManager); return NS_OK; } return NS_ERROR_FAILURE; @@ -886,10 +922,8 @@ nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsII nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - nsIEventListenerManager *manager; - - if (NS_OK == GetListenerManager(&manager)) { - manager->RemoveEventListener(aListener, aIID); + if (nsnull != mListenerManager) { + mListenerManager->RemoveEventListener(aListener, aIID); return NS_OK; } return NS_ERROR_FAILURE; @@ -897,10 +931,11 @@ nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const n nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener) { - nsIEventListenerManager *manager; + nsIEventListenerManager *mManager; - if (NS_OK == GetListenerManager(&manager)) { - manager->CaptureEvent(aListener); + if (NS_OK == GetListenerManager(&mManager)) { + mManager->CaptureEvent(aListener); + NS_RELEASE(mManager); return NS_OK; } return NS_ERROR_FAILURE; @@ -908,17 +943,13 @@ nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener) nsresult nsDocument::ReleaseEvent(nsIDOMEventListener *aListener) { - nsIEventListenerManager *manager; - - if (NS_OK == GetListenerManager(&manager)) { - manager->ReleaseEvent(aListener); + if (nsnull != mListenerManager) { + mListenerManager->ReleaseEvent(aListener); return NS_OK; } return NS_ERROR_FAILURE; } - - /** * Returns the Selection Object */ diff --git a/layout/base/src/nsDocument.h b/layout/base/src/nsDocument.h index 141fb7247662..23444122a849 100644 --- a/layout/base/src/nsDocument.h +++ b/layout/base/src/nsDocument.h @@ -246,8 +246,9 @@ public: NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult); NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, nsEventStatus& aEventStatus); diff --git a/layout/base/src/nsFrame.cpp b/layout/base/src/nsFrame.cpp index d9bef2d379c1..08e0aade84be 100644 --- a/layout/base/src/nsFrame.cpp +++ b/layout/base/src/nsFrame.cpp @@ -25,6 +25,7 @@ #include "nsIPresContext.h" #include "nsCRT.h" #include "nsGUIEvent.h" +#include "nsDOMEvent.h" #include "nsStyleConsts.h" #include "nsIPresShell.h" #include "prlog.h" @@ -32,7 +33,6 @@ #include #include "nsIPtr.h" #include "nsISizeOfHandler.h" -#include "nsIEventStateManager.h" #include "nsIDOMText.h" #include "nsSelectionRange.h" @@ -548,13 +548,7 @@ NS_METHOD nsFrame::HandleEvent(nsIPresContext& aPresContext, aEventStatus = nsEventStatus_eIgnore; if (nsnull != mContent) { - nsIEventStateManager *manager = nsnull; - aPresContext.GetEventStateManager(&manager); - if (nsnull != manager) { - manager->SetEventTarget((nsISupports*)mContent); - NS_RELEASE(manager); - } - mContent->HandleDOMEvent(aPresContext, aEvent, nsnull, aEventStatus); + mContent->HandleDOMEvent(aPresContext, (nsEvent*)aEvent, nsnull, DOM_EVENT_INIT, aEventStatus); } #if DO_SELECTION diff --git a/layout/base/tests/TestContainerFrame.cpp b/layout/base/tests/TestContainerFrame.cpp index 77a5246cf835..3909e4b12691 100644 --- a/layout/base/tests/TestContainerFrame.cpp +++ b/layout/base/tests/TestContainerFrame.cpp @@ -87,7 +87,7 @@ public: void List(FILE* out = stdout, PRInt32 aIndent = 0) const {;} NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const { return NS_OK; } - NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsIDOMEvent* aDOMEvent, nsEventStatus& aEventStatus) + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags, nsEventStatus& aEventStatus) {return NS_OK;} NS_DECL_ISUPPORTS diff --git a/layout/events/public/Makefile b/layout/events/public/Makefile index da3ff3bd61e8..9f817da72c03 100644 --- a/layout/events/public/Makefile +++ b/layout/events/public/Makefile @@ -22,6 +22,7 @@ MODULE = raptor EXPORTS = \ nsIEventListenerManager.h \ nsIEventStateManager.h \ + nsIPrivateDOMEvent.h \ $(NULL) include $(DEPTH)/config/config.mk diff --git a/layout/events/public/makefile.win b/layout/events/public/makefile.win index c1fcc7bbb8d6..51c3e4d81d9c 100644 --- a/layout/events/public/makefile.win +++ b/layout/events/public/makefile.win @@ -21,6 +21,7 @@ IGNORE_MANIFEST=1 EXPORTS = \ nsIEventListenerManager.h \ nsIEventStateManager.h \ + nsIPrivateDOMEvent.h \ $(NULL) MODULE=raptor diff --git a/layout/events/public/nsIEventListenerManager.h b/layout/events/public/nsIEventListenerManager.h index 295e079287f8..c5a325dc2357 100644 --- a/layout/events/public/nsIEventListenerManager.h +++ b/layout/events/public/nsIEventListenerManager.h @@ -66,9 +66,9 @@ public: */ virtual nsresult HandleEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) = 0; + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + nsEventStatus& aEventStatus) = 0; /** * Captures all events designated for descendant objects at the current level. diff --git a/layout/events/public/nsIEventStateManager.h b/layout/events/public/nsIEventStateManager.h index cb6d57e54c1c..24c440b4c7da 100644 --- a/layout/events/public/nsIEventStateManager.h +++ b/layout/events/public/nsIEventStateManager.h @@ -32,9 +32,9 @@ class nsIDOMEvent; * Event listener manager interface. */ #define NS_IEVENTSTATEMANAGER_IID \ -{ /* c8488290-07ce-11d2-bd88-00805f8ae3f4 */ \ -0xc8488290, 0x07ce, 0x11d2, \ -{0xbd, 0x88, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } +{ /* 80a98c80-2036-11d2-bd89-00805f8ae3f4 */ \ +0x80a98c80, 0x2036, 0x11d2, \ +{0xbd, 0x89, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } class nsIEventStateManager : public nsISupports { diff --git a/layout/events/public/nsIPrivateDOMEvent.h b/layout/events/public/nsIPrivateDOMEvent.h new file mode 100644 index 000000000000..185981de46d0 --- /dev/null +++ b/layout/events/public/nsIPrivateDOMEvent.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsIPrivateDOMEvent_h__ +#define nsIPrivateDOMEvent_h__ + +#include "nsGUIEvent.h" +#include "nsISupports.h" + +class nsIPresContext; + +/* + * Event listener manager interface. + */ +#define NS_IPRIVATEDOMEVENT_IID \ +{ /* 80a98c80-2036-11d2-bd89-00805f8ae3f4 */ \ +0x80a98c80, 0x2036, 0x11d2, \ +{0xbd, 0x89, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} } + +class nsIPrivateDOMEvent : public nsISupports { + +public: + NS_IMETHOD DuplicatePrivateData() = 0; +}; + +extern nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsIPresContext& aPresContext, nsEvent *aEvent); + +#endif // nsIPrivateDOMEvent_h__ diff --git a/layout/events/src/Makefile b/layout/events/src/Makefile index b97d5f22f096..973a0bd7a787 100644 --- a/layout/events/src/Makefile +++ b/layout/events/src/Makefile @@ -32,6 +32,7 @@ MODULE = raptor EXPORTS = \ nsEventListenerManager.h \ nsEventStateManager.h \ + nsDOMEvent.h \ $(NULL) REQUIRES = xpcom raptor dom js diff --git a/layout/events/src/makefile.win b/layout/events/src/makefile.win index 111651d3103e..fb627926014f 100644 --- a/layout/events/src/makefile.win +++ b/layout/events/src/makefile.win @@ -37,7 +37,7 @@ CPP_OBJS= .\$(OBJDIR)\nsEventListenerManager.obj \ $(NULL) -EXPORTS= nsEventListenerManager.h nsEventStateManager.h +EXPORTS= nsEventListenerManager.h nsEventStateManager.h nsDOMEvent.h LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor \ -I$(PUBLIC)\dom -I$(PUBLIC)\js diff --git a/layout/events/src/nsDOMEvent.cpp b/layout/events/src/nsDOMEvent.cpp index 8350b106f766..8d4828953e30 100644 --- a/layout/events/src/nsDOMEvent.cpp +++ b/layout/events/src/nsDOMEvent.cpp @@ -18,17 +18,12 @@ #include "nsDOMEvent.h" #include "nsIDOMNode.h" +#include "nsIEventStateManager.h" static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIDOMEventIID, NS_IDOMEVENT_IID); static NS_DEFINE_IID(kIDOMNSEventIID, NS_IDOMNSEVENT_IID); - - -enum mEventEnum { - onmousedown=0, onmouseup=1, onclick=2, ondblclick=3, onmouseover=4, onmouseout=5, - onmousemove=6, onkeydown=7, onkeyup=8, onkeypress=9, onfocus=10, onblur=11, - onload=12, onabort=13, onerror=14 -}; +static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static char* mEventNames[] = { "onmousedown", "onmouseup", "onclick", "ondblclick", "onmouseover", "onmouseout", @@ -36,13 +31,15 @@ static char* mEventNames[] = { "onload", "onabort", "onerror" }; -nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext) { - kPresContext = aPresContext; - NS_ADDREF(kPresContext); +nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent) { + mPresContext = aPresContext; + NS_ADDREF(mPresContext); + mEvent = aEvent; + NS_INIT_REFCNT(); } nsDOMEvent::~nsDOMEvent() { - NS_RELEASE(kPresContext); + NS_RELEASE(mPresContext); } NS_IMPL_ADDREF(nsDOMEvent) @@ -65,13 +62,18 @@ nsresult nsDOMEvent::QueryInterface(const nsIID& aIID, AddRef(); return NS_OK; } + if (aIID.Equals(kIPrivateDOMEventIID)) { + *aInstancePtrResult = (void*) ((nsIPrivateDOMEvent*)this); + AddRef(); + return NS_OK; + } return NS_NOINTERFACE; } // nsIDOMEventInterface NS_METHOD nsDOMEvent::GetType(nsString& aType) { - const char* mName = GetEventName(kEvent->message); + const char* mName = GetEventName(mEvent->message); if (nsnull != mName) { aType = nsString(mName); @@ -88,7 +90,15 @@ NS_METHOD nsDOMEvent::SetType(const nsString& aType) NS_METHOD nsDOMEvent::GetTarget(nsIDOMNode** aTarget) { - return kTarget->QueryInterface(kIDOMNodeIID, (void**)aTarget); + nsIEventStateManager *mManager; + nsISupports *mTarget; + + if (NS_OK == mPresContext->GetEventStateManager(&mManager)) { + mManager->GetEventTarget(&mTarget); + NS_RELEASE(mManager); + } + + return mTarget->QueryInterface(kIDOMNodeIID, (void**)aTarget); } NS_METHOD nsDOMEvent::SetTarget(nsIDOMNode* aTarget) @@ -118,7 +128,7 @@ NS_METHOD nsDOMEvent::SetScreenY(PRInt32 aScreenY) NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX) { - *aClientX = NS_TO_INT_ROUND(kEvent->point.x * kPresContext->GetTwipsToPixels()); + *aClientX = NS_TO_INT_ROUND(mEvent->point.x * mPresContext->GetTwipsToPixels()); return NS_OK; } @@ -129,7 +139,7 @@ NS_METHOD nsDOMEvent::SetClientX(PRInt32 aClientX) NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY) { - *aClientY = NS_TO_INT_ROUND(kEvent->point.y * kPresContext->GetTwipsToPixels()); + *aClientY = NS_TO_INT_ROUND(mEvent->point.y * mPresContext->GetTwipsToPixels()); return NS_OK; } @@ -140,7 +150,7 @@ NS_METHOD nsDOMEvent::SetClientY(PRInt32 aClientY) NS_METHOD nsDOMEvent::GetAltKey(PRBool* aIsDown) { - *aIsDown = ((nsInputEvent*)kEvent)->isAlt; + *aIsDown = ((nsInputEvent*)mEvent)->isAlt; return NS_OK; } @@ -151,7 +161,7 @@ NS_METHOD nsDOMEvent::SetAltKey(PRBool aAltKey) NS_METHOD nsDOMEvent::GetCtrlKey(PRBool* aIsDown) { - *aIsDown = ((nsInputEvent*)kEvent)->isControl; + *aIsDown = ((nsInputEvent*)mEvent)->isControl; return NS_OK; } @@ -162,7 +172,7 @@ NS_METHOD nsDOMEvent::SetCtrlKey(PRBool aCtrlKey) NS_METHOD nsDOMEvent::GetShiftKey(PRBool* aIsDown) { - *aIsDown = ((nsInputEvent*)kEvent)->isShift; + *aIsDown = ((nsInputEvent*)mEvent)->isShift; return NS_OK; } @@ -193,10 +203,10 @@ NS_METHOD nsDOMEvent::SetCharCode(PRUint32 aCharCode) NS_METHOD nsDOMEvent::GetKeyCode(PRUint32* aKeyCode) { - switch (kEvent->message) { + switch (mEvent->message) { case NS_KEY_UP: case NS_KEY_DOWN: - *aKeyCode = ((nsKeyEvent*)kEvent)->keyCode; + *aKeyCode = ((nsKeyEvent*)mEvent)->keyCode; break; default: return NS_ERROR_FAILURE; @@ -211,7 +221,7 @@ NS_METHOD nsDOMEvent::SetKeyCode(PRUint32 aKeyCode) NS_METHOD nsDOMEvent::GetButton(PRUint32* aButton) { - switch (kEvent->message) { + switch (mEvent->message) { case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_LEFT_DOUBLECLICK: @@ -258,15 +268,9 @@ NS_METHOD nsDOMEvent::SetLayerY(PRInt32 aLayerY) return NS_ERROR_NOT_IMPLEMENTED; } -NS_METHOD nsDOMEvent::SetGUIEvent(nsGUIEvent *aEvent) +NS_METHOD nsDOMEvent::DuplicatePrivateData() { - kEvent = aEvent; - return NS_OK; -} - -NS_METHOD nsDOMEvent::SetEventTarget(nsISupports *aTarget) -{ - kTarget = aTarget; + //XXX Write me! return NS_OK; } @@ -276,34 +280,44 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType) case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: - return mEventNames[onmousedown]; + return mEventNames[eDOMEvents_mousedown]; break; case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: - return mEventNames[onmouseup]; + return mEventNames[eDOMEvents_mouseup]; break; case NS_MOUSE_LEFT_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK: - return mEventNames[ondblclick]; + return mEventNames[eDOMEvents_dblclick]; break; - /*case NS_MOUSE_ENTER: - return mEventNames[onmouseover]; + case NS_MOUSE_ENTER: + return mEventNames[eDOMEvents_mouseover]; break; case NS_MOUSE_EXIT: - return mEventNames[onmouseout]; - break;*/ + return mEventNames[eDOMEvents_mouseout]; + break; case NS_MOUSE_MOVE: - return mEventNames[onmousemove]; + return mEventNames[eDOMEvents_mousemove]; break; case NS_KEY_UP: - return mEventNames[onkeyup]; + return mEventNames[eDOMEvents_keyup]; break; case NS_KEY_DOWN: - return mEventNames[onkeydown]; + return mEventNames[eDOMEvents_keydown]; break; default: break; } return nsnull; } + +nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsIPresContext& aPresContext, nsEvent *aEvent) +{ + nsDOMEvent* it = new nsDOMEvent(&aPresContext, aEvent); + if (nsnull == it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return it->QueryInterface(kIDOMEventIID, (void **) aInstancePtrResult); +} diff --git a/layout/events/src/nsDOMEvent.h b/layout/events/src/nsDOMEvent.h index 2f1847ee3f43..8ed450596642 100644 --- a/layout/events/src/nsDOMEvent.h +++ b/layout/events/src/nsDOMEvent.h @@ -21,22 +21,27 @@ #include "nsIDOMEvent.h" #include "nsISupports.h" +#include "nsIPrivateDOMEvent.h" + #include "nsIPresContext.h" #include "nsPoint.h" #include "nsGUIEvent.h" class nsIContent; -class nsDOMEvent : public nsIDOMEvent, public nsIDOMNSEvent { +class nsDOMEvent : public nsIDOMEvent, public nsIDOMNSEvent, public nsIPrivateDOMEvent { + +#define DOM_EVENT_INIT 0x0001 +#define DOM_EVENT_BUBBLE 0x0002 +#define DOM_EVENT_CAPTURE 0x0004 public: - - enum nsEventStatus { - nsEventStatus_eIgnore, // The event is ignored, do default processing - nsEventStatus_eConsumeNoDefault, // The event is consumed, don't do default processing - nsEventStatus_eConsumeDoDefault // The event is consumed, but do default processing + enum nsDOMEvents { + eDOMEvents_mousedown=0, eDOMEvents_mouseup=1, eDOMEvents_click=2, eDOMEvents_dblclick=3, eDOMEvents_mouseover=4, eDOMEvents_mouseout=5, + eDOMEvents_mousemove=6, eDOMEvents_keydown=7, eDOMEvents_keyup=8, eDOMEvents_keypress=9, eDOMEvents_focus=10, eDOMEvents_blur=11, + eDOMEvents_load=12, eDOMEvents_abort=13, eDOMEvents_error=14 }; - nsDOMEvent(nsIPresContext* aPresContext); + nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent); virtual ~nsDOMEvent(); NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); @@ -83,25 +88,24 @@ public: NS_IMETHOD GetButton(PRUint32* aButton); NS_IMETHOD SetButton(PRUint32 aButton); - // nsINSEventInterface + // nsIDOMNSEvent interface NS_IMETHOD GetLayerX(PRInt32* aLayerX); NS_IMETHOD SetLayerX(PRInt32 aLayerX); NS_IMETHOD GetLayerY(PRInt32* aLayerY); NS_IMETHOD SetLayerY(PRInt32 aLayerY); - // Local functions - NS_IMETHOD SetGUIEvent(nsGUIEvent *aEvent); - NS_IMETHOD SetEventTarget(nsISupports *aTarget); + // nsIPrivateDOMEvent interface + NS_IMETHOD DuplicatePrivateData(); protected: PRUint32 mRefCnt : 31; - nsGUIEvent *kEvent; - nsISupports *kTarget; - nsIPresContext *kPresContext; + nsEvent *mEvent; + nsIPresContext *mPresContext; const char* GetEventName(PRUint32 aEventType); }; + #endif // nsDOMEvent_h__ diff --git a/layout/events/src/nsEventListenerManager.cpp b/layout/events/src/nsEventListenerManager.cpp index 7556d31bc5fc..4788d06f820b 100644 --- a/layout/events/src/nsEventListenerManager.cpp +++ b/layout/events/src/nsEventListenerManager.cpp @@ -29,6 +29,7 @@ #include "nsIDOMLoadListener.h" #include "nsIDOMDragListener.h" #include "nsIEventStateManager.h" +#include "nsIPrivateDOMEvent.h" static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID); @@ -40,7 +41,8 @@ static NS_DEFINE_IID(kIDOMLoadListenerIID, NS_IDOMLOADLISTENER_IID); static NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID); static NS_DEFINE_IID(kIDOMEventIID, NS_IDOMEVENT_IID); -nsEventListenerManager::nsEventListenerManager() { +nsEventListenerManager::nsEventListenerManager() +{ mEventListeners = nsnull; mMouseListeners = nsnull; mMouseMotionListeners = nsnull; @@ -48,9 +50,18 @@ nsEventListenerManager::nsEventListenerManager() { mLoadListeners = nsnull; mFocusListeners = nsnull; mDragListeners = nsnull; + NS_INIT_REFCNT(); } -nsEventListenerManager::~nsEventListenerManager() { +nsEventListenerManager::~nsEventListenerManager() +{ + ReleaseListeners(mEventListeners); + ReleaseListeners(mMouseListeners); + ReleaseListeners(mMouseMotionListeners); + ReleaseListeners(mKeyListeners); + ReleaseListeners(mLoadListeners); + ReleaseListeners(mFocusListeners); + ReleaseListeners(mDragListeners); } NS_IMPL_ADDREF(nsEventListenerManager) @@ -71,48 +82,49 @@ nsresult nsEventListenerManager::QueryInterface(const nsIID& aIID, return NS_NOINTERFACE; } -nsresult nsEventListenerManager::TranslateGUI2DOM(nsGUIEvent*& aGUIEvent, - nsIPresContext& aPresContext, - nsIDOMEvent** aDOMEvent) +nsVoidArray** nsEventListenerManager::GetListenersByIID(const nsIID& aIID) { - nsIEventStateManager *mManager; - nsISupports *mTarget; - - nsDOMEvent* it = new nsDOMEvent(&aPresContext); - if (nsnull == it) { - return NS_ERROR_OUT_OF_MEMORY; + if (aIID.Equals(kIDOMMouseListenerIID)) { + return &mMouseListeners; } - - it->SetGUIEvent(aGUIEvent); - if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { - mManager->GetEventTarget(&mTarget); - NS_RELEASE(mManager); + else if (aIID.Equals(kIDOMMouseMotionListenerIID)) { + return &mMouseMotionListeners; } - it->SetEventTarget(mTarget); + else if (aIID.Equals(kIDOMKeyListenerIID)) { + return &mKeyListeners; + } + else if (aIID.Equals(kIDOMLoadListenerIID)) { + return &mLoadListeners; + } + else if (aIID.Equals(kIDOMFocusListenerIID)) { + return &mFocusListeners; + } + else if (aIID.Equals(kIDOMDragListenerIID)) { + return &mDragListeners; + } + return nsnull; +} - return it->QueryInterface(kIDOMEventIID, (void **) aDOMEvent); +void nsEventListenerManager::ReleaseListeners(nsVoidArray* aListeners) +{ + if (nsnull != aListeners) { + PRInt32 i, count = aListeners->Count(); + nsIDOMEventListener *mElement; + for (i = 0; i < count; i++) { + mElement = (nsIDOMEventListener *)aListeners->ElementAt(i); + if (mElement != nsnull) { + NS_RELEASE(mElement); + } + } + delete aListeners; + } } nsresult nsEventListenerManager::GetEventListeners(nsVoidArray **aListeners, const nsIID& aIID) { - if (aIID.Equals(kIDOMMouseListenerIID)) { - *aListeners = mMouseListeners; - } - if (aIID.Equals(kIDOMMouseMotionListenerIID)) { - *aListeners = mMouseMotionListeners; - } - if (aIID.Equals(kIDOMKeyListenerIID)) { - *aListeners = mKeyListeners; - } - if (aIID.Equals(kIDOMLoadListenerIID)) { - *aListeners = mLoadListeners; - } - if (aIID.Equals(kIDOMFocusListenerIID)) { - *aListeners = mFocusListeners; - } - if (aIID.Equals(kIDOMDragListenerIID)) { - *aListeners = mDragListeners; - } + nsVoidArray** mListeners = GetListenersByIID(aIID); + + *aListeners = *mListeners; return NS_OK; } @@ -124,42 +136,20 @@ nsresult nsEventListenerManager::GetEventListeners(nsVoidArray **aListeners, con nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - if (aIID.Equals(kIDOMMouseListenerIID)) { - if (nsnull == mMouseListeners) { - mMouseListeners = new nsVoidArray(); - mMouseListeners->InsertElementAt((void*)aListener, mMouseListeners->Count()); - } + nsVoidArray** mListeners = GetListenersByIID(aIID); + + if (nsnull == *mListeners) { + *mListeners = new nsVoidArray(); } - if (aIID.Equals(kIDOMMouseMotionListenerIID)) { - if (nsnull == mMouseMotionListeners) { - mMouseMotionListeners = new nsVoidArray(); - mMouseMotionListeners->InsertElementAt((void*)aListener, mMouseMotionListeners->Count()); - } - } - if (aIID.Equals(kIDOMKeyListenerIID)) { - if (nsnull == mKeyListeners) { - mKeyListeners = new nsVoidArray(); - mKeyListeners->InsertElementAt((void*)aListener, mKeyListeners->Count()); - } - } - if (aIID.Equals(kIDOMLoadListenerIID)) { - if (nsnull == mLoadListeners) { - mLoadListeners = new nsVoidArray(); - mLoadListeners->InsertElementAt((void*)aListener, mLoadListeners->Count()); - } - } - if (aIID.Equals(kIDOMFocusListenerIID)) { - if (nsnull == mFocusListeners) { - mFocusListeners = new nsVoidArray(); - mFocusListeners->InsertElementAt((void*)aListener, mFocusListeners->Count()); - } - } - if (aIID.Equals(kIDOMDragListenerIID)) { - if (nsnull == mDragListeners) { - mDragListeners = new nsVoidArray(); - mDragListeners->InsertElementAt((void*)aListener, mDragListeners->Count()); - } + + if (nsnull == *mListeners) { + return NS_ERROR_OUT_OF_MEMORY; } + + (*mListeners)->InsertElementAt((void*)aListener, (*mListeners)->Count()); + + NS_ADDREF(aListener); + return NS_OK; } @@ -170,43 +160,13 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - if (aIID.Equals(kIDOMMouseListenerIID)) { - if (nsnull == mMouseListeners) { - mMouseListeners = new nsVoidArray(); - mMouseListeners->RemoveElement((void*)aListener); - } + nsVoidArray** mListeners = GetListenersByIID(aIID); + + if (nsnull != *mListeners && PR_TRUE == (*mListeners)->RemoveElement((void*)aListener)) { + NS_RELEASE(aListener); + return NS_OK; } - if (aIID.Equals(kIDOMMouseMotionListenerIID)) { - if (nsnull == mMouseMotionListeners) { - mMouseMotionListeners = new nsVoidArray(); - mMouseMotionListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMKeyListenerIID)) { - if (nsnull == mKeyListeners) { - mKeyListeners = new nsVoidArray(); - mKeyListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMLoadListenerIID)) { - if (nsnull == mLoadListeners) { - mLoadListeners = new nsVoidArray(); - mLoadListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMFocusListenerIID)) { - if (nsnull == mFocusListeners) { - mFocusListeners = new nsVoidArray(); - mFocusListeners->RemoveElement((void*)aListener); - } - } - if (aIID.Equals(kIDOMDragListenerIID)) { - if (nsnull == mDragListeners) { - mDragListeners = new nsVoidArray(); - mDragListeners->RemoveElement((void*)aListener); - } - } - return NS_OK; + return NS_ERROR_FAILURE; } /** @@ -215,9 +175,9 @@ nsresult nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListe */ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + nsEventStatus& aEventStatus) { nsresult mRet = NS_OK; @@ -233,10 +193,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_MOUSE_ENTER: case NS_MOUSE_EXIT: if (nsnull != mMouseListeners) { - if (nsnull == aDOMEvent) { - TranslateGUI2DOM(aEvent, aPresContext, &aDOMEvent); + if (nsnull == *aDOMEvent) { + mRet = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent); } - if (nsnull != aDOMEvent) { + if (NS_OK == mRet) { for (int i=0; iCount(); i++) { nsIDOMEventListener *mEventListener; nsIDOMMouseListener *mMouseListener; @@ -248,22 +208,22 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_MOUSE_LEFT_BUTTON_DOWN: case NS_MOUSE_MIDDLE_BUTTON_DOWN: case NS_MOUSE_RIGHT_BUTTON_DOWN: - mRet = mMouseListener->MouseDown(aDOMEvent); + mRet = mMouseListener->MouseDown(*aDOMEvent); break; case NS_MOUSE_LEFT_BUTTON_UP: case NS_MOUSE_MIDDLE_BUTTON_UP: case NS_MOUSE_RIGHT_BUTTON_UP: - mRet = mMouseListener->MouseUp(aDOMEvent); + mRet = mMouseListener->MouseUp(*aDOMEvent); break; case NS_MOUSE_LEFT_DOUBLECLICK: case NS_MOUSE_RIGHT_DOUBLECLICK: - mRet = mMouseListener->MouseDblClick(aDOMEvent); + mRet = mMouseListener->MouseDblClick(*aDOMEvent); break; case NS_MOUSE_ENTER: - mRet = mMouseListener->MouseOver(aDOMEvent); + mRet = mMouseListener->MouseOver(*aDOMEvent); break; case NS_MOUSE_EXIT: - mRet = mMouseListener->MouseOut(aDOMEvent); + mRet = mMouseListener->MouseOut(*aDOMEvent); break; default: break; @@ -271,7 +231,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, NS_RELEASE(mMouseListener); } else { - mRet = mEventListener->ProcessEvent(aDOMEvent); + mRet = mEventListener->ProcessEvent(*aDOMEvent); } aEventStatus = (NS_OK == mRet) ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault; } @@ -281,10 +241,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_MOUSE_MOVE: if (nsnull != mMouseMotionListeners) { - if (nsnull == aDOMEvent) { - TranslateGUI2DOM(aEvent, aPresContext, &aDOMEvent); + if (nsnull == *aDOMEvent) { + mRet = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent); } - if (nsnull != aDOMEvent) { + if (NS_OK == mRet) { for (int i=0; iCount(); i++) { nsIDOMEventListener *mEventListener; nsIDOMMouseMotionListener *mMouseMotionListener; @@ -294,7 +254,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, if (NS_OK == mEventListener->QueryInterface(kIDOMMouseMotionListenerIID, (void**)&mMouseMotionListener)) { switch(aEvent->message) { case NS_MOUSE_MOVE: - mRet = mMouseMotionListener->MouseMove(aDOMEvent); + mRet = mMouseMotionListener->MouseMove(*aDOMEvent); break; default: break; @@ -302,7 +262,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, NS_RELEASE(mMouseMotionListener); } else { - mRet = mEventListener->ProcessEvent(aDOMEvent); + mRet = mEventListener->ProcessEvent(*aDOMEvent); } aEventStatus = (NS_OK == mRet) ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault; } @@ -313,10 +273,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, case NS_KEY_UP: case NS_KEY_DOWN: if (nsnull != mKeyListeners) { - if (nsnull == aDOMEvent) { - TranslateGUI2DOM(aEvent, aPresContext, &aDOMEvent); + if (nsnull == *aDOMEvent) { + mRet = NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent); } - if (nsnull != aDOMEvent) { + if (NS_OK == mRet) { for (int i=0; iCount(); i++) { nsIDOMEventListener *mEventListener; nsIDOMKeyListener *mKeyListener; @@ -326,10 +286,10 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, if (NS_OK == mEventListener->QueryInterface(kIDOMKeyListenerIID, (void**)&mKeyListener)) { switch(aEvent->message) { case NS_KEY_UP: - mRet = mKeyListener->KeyUp(aDOMEvent); + mRet = mKeyListener->KeyUp(*aDOMEvent); break; case NS_KEY_DOWN: - mRet = mKeyListener->KeyDown(aDOMEvent); + mRet = mKeyListener->KeyDown(*aDOMEvent); break; default: break; @@ -337,7 +297,7 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext& aPresContext, NS_RELEASE(mKeyListener); } else { - mRet = mEventListener->ProcessEvent(aDOMEvent); + mRet = mEventListener->ProcessEvent(*aDOMEvent); } aEventStatus = (NS_OK == mRet) ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault; } diff --git a/layout/events/src/nsEventListenerManager.h b/layout/events/src/nsEventListenerManager.h index a650bda9103b..f0371d30a0f3 100644 --- a/layout/events/src/nsEventListenerManager.h +++ b/layout/events/src/nsEventListenerManager.h @@ -36,6 +36,10 @@ public: NS_IMETHOD_(nsrefcnt) AddRef(); NS_IMETHOD_(nsrefcnt) Release(); + nsVoidArray** GetListenersByIID(const nsIID& aIID); + + void ReleaseListeners(nsVoidArray* aListeners); + /** * Retrieves events listeners of all types. * @param @@ -55,16 +59,12 @@ public: virtual nsresult CaptureEvent(nsIDOMEventListener *aListener); virtual nsresult ReleaseEvent(nsIDOMEventListener *aListener); - virtual nsresult HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsIDOMEvent* aDOMEvent, nsEventStatus& aEventStatus); + virtual nsresult HandleEvent(nsIPresContext& aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, nsEventStatus& aEventStatus); protected: PRUint32 mRefCnt : 31; - virtual nsresult TranslateGUI2DOM(nsGUIEvent*& aGUIEvent, - nsIPresContext& aPresContext, - nsIDOMEvent** aDOMEvent); - nsVoidArray* mEventListeners; nsVoidArray* mMouseListeners; nsVoidArray* mMouseMotionListeners; diff --git a/layout/events/src/nsEventStateManager.cpp b/layout/events/src/nsEventStateManager.cpp index f68dacbc6dd2..bbbf0707a03c 100644 --- a/layout/events/src/nsEventStateManager.cpp +++ b/layout/events/src/nsEventStateManager.cpp @@ -74,7 +74,7 @@ NS_METHOD nsEventStateManager::SetLastMouseOverContent(nsIContent *aContent) NS_IF_RELEASE(mLastMouseOverContent); mLastMouseOverContent = aContent; - NS_ADDREF(mLastMouseOverContent); + NS_IF_ADDREF(mLastMouseOverContent); return NS_OK; } diff --git a/layout/html/base/src/nsHTMLContent.cpp b/layout/html/base/src/nsHTMLContent.cpp index 21f9d01fd8cc..d3a11db1f75a 100644 --- a/layout/html/base/src/nsHTMLContent.cpp +++ b/layout/html/base/src/nsHTMLContent.cpp @@ -26,9 +26,11 @@ #include "nsISupportsArray.h" #include "nsCRT.h" #include "nsIDocument.h" -#include "nsIEventListenerManager.h" #include "nsEventListenerManager.h" +#include "nsIEventStateManager.h" #include "nsISizeOfHandler.h" +#include "nsDOMEvent.h" +#include "nsIPrivateDOMEvent.h" static NS_DEFINE_IID(kIContentDelegateIID, NS_ICONTENTDELEGATE_IID); static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); @@ -38,6 +40,7 @@ static NS_DEFINE_IID(kIHTMLContent, NS_IHTMLCONTENT_IID); static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID); static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); static NS_DEFINE_IID(kIDOMEventReceiverIID, NS_IDOMEVENTRECEIVER_IID); +static NS_DEFINE_IID(kIPrivateDOMEventIID, NS_IPRIVATEDOMEVENT_IID); static nsIContentDelegate* gContentDelegate; @@ -154,6 +157,8 @@ nsHTMLContent::~nsHTMLContent() gContentDelegate = nsnull; } } + + NS_IF_RELEASE(mListenerManager); } NS_IMPL_ADDREF(nsHTMLContent) @@ -589,9 +594,9 @@ nsresult nsHTMLContent::GetListenerManager(nsIEventListenerManager **aInstancePt return NS_ERROR_OUT_OF_MEMORY; } - if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) { mListenerManager = l; + NS_ADDREF(mListenerManager); return NS_OK; } @@ -601,10 +606,11 @@ nsresult nsHTMLContent::GetListenerManager(nsIEventListenerManager **aInstancePt nsresult nsHTMLContent::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - nsIEventListenerManager *manager; + nsIEventListenerManager *mManager; - if (NS_OK == GetListenerManager(&manager)) { - manager->AddEventListener(aListener, aIID); + if (NS_OK == GetListenerManager(&mManager)) { + mManager->AddEventListener(aListener, aIID); + NS_RELEASE(mManager); return NS_OK; } return NS_ERROR_FAILURE; @@ -612,20 +618,32 @@ nsresult nsHTMLContent::AddEventListener(nsIDOMEventListener *aListener, const n nsresult nsHTMLContent::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) { - nsIEventListenerManager *manager; - - if (NS_OK == GetListenerManager(&manager)) { - manager->RemoveEventListener(aListener, aIID); + if (nsnull != mListenerManager) { + mListenerManager->RemoveEventListener(aListener, aIID); return NS_OK; } return NS_ERROR_FAILURE; } nsresult nsHTMLContent::HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus) + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus) { + nsresult mRet = NS_OK; + + if (DOM_EVENT_INIT == aFlags) { + nsIEventStateManager *mManager; + if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { + mManager->SetEventTarget((nsIHTMLContent*)this); + NS_RELEASE(mManager); + } + + nsIDOMEvent* mDOMEvent = nsnull; + aDOMEvent = &mDOMEvent; + } + //Capturing stage //Local handling stage @@ -635,10 +653,25 @@ nsresult nsHTMLContent::HandleDOMEvent(nsIPresContext& aPresContext, //Bubbling stage if (mParent != nsnull) { - return mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aEventStatus); + mRet = mParent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, DOM_EVENT_BUBBLE, aEventStatus); } - return NS_OK; + if (DOM_EVENT_INIT == aFlags) { + // We're leaving the DOM event loop so if we created a DOM event, release here. + if (nsnull != *aDOMEvent) { + if (0 != (*aDOMEvent)->Release()) { + //Okay, so someone in the DOM loop (a listener, JS object) still has a ref to the DOM Event but + //the internal data hasn't been malloc'd. Force a copy of the data here so the DOM Event is still valid. + nsIPrivateDOMEvent *mPrivateEvent; + if (NS_OK == (*aDOMEvent)->QueryInterface(kIPrivateDOMEventIID, (void**)&mPrivateEvent)) { + mPrivateEvent->DuplicatePrivateData(); + NS_RELEASE(mPrivateEvent); + } + } + } + } + + return mRet; } // XXX i18n: this is wrong (?) because we need to know the outgoing diff --git a/layout/html/base/src/nsHTMLContent.h b/layout/html/base/src/nsHTMLContent.h index 73dcd2daa7e6..24f69c8117dc 100644 --- a/layout/html/base/src/nsHTMLContent.h +++ b/layout/html/base/src/nsHTMLContent.h @@ -137,8 +137,9 @@ public: NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, nsEventStatus& aEventStatus); protected: diff --git a/layout/html/base/src/nsHTMLTagContent.cpp b/layout/html/base/src/nsHTMLTagContent.cpp index 3f981b6c037d..622e45589308 100644 --- a/layout/html/base/src/nsHTMLTagContent.cpp +++ b/layout/html/base/src/nsHTMLTagContent.cpp @@ -572,7 +572,7 @@ nsresult nsHTMLTagContent::SetScriptEventListener(JSContext *aContext, REFNSIID } if (nsnull != mScriptObject) { - nsIEventListenerManager *mManager; + nsIEventListenerManager *mManager = nsnull; nsVoidArray *mListeners; if (NS_OK == GetListenerManager(&mManager) && @@ -586,6 +586,7 @@ nsresult nsHTMLTagContent::SetScriptEventListener(JSContext *aContext, REFNSIID mEventListener = (nsIDOMEventListener*)mListeners->ElementAt(i); if (NS_OK == mEventListener->QueryInterface(kIScriptEventListenerIID, (void**)&mScriptListener)) { NS_RELEASE(mScriptListener); + NS_RELEASE(mManager); return NS_OK; } } @@ -594,9 +595,12 @@ nsresult nsHTMLTagContent::SetScriptEventListener(JSContext *aContext, REFNSIID nsIDOMEventListener *mScriptListener; if (NS_OK == NS_NewScriptEventListener(&mScriptListener, mScriptCX, mScriptObject)) { mManager->AddEventListener(mScriptListener, aListenerTypeIID); + NS_RELEASE(mScriptListener); + NS_RELEASE(mManager); return NS_OK; } } + NS_IF_RELEASE(mManager); } return NS_ERROR_FAILURE; } @@ -880,13 +884,14 @@ void nsHTMLTagContent::TriggerLink(nsIPresContext& aPresContext, } nsresult nsHTMLTagContent::HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, nsEventStatus& aEventStatus) { nsresult ret = NS_OK; - ret = nsHTMLContent::HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aEventStatus); + ret = nsHTMLContent::HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); if (NS_OK == ret && nsEventStatus_eIgnore == aEventStatus) { switch (aEvent->message) { @@ -904,25 +909,24 @@ nsresult nsHTMLTagContent::HandleDOMEvent(nsIPresContext& aPresContext, // XXX Bring up a contextual menu provided by the application break; -// XXX kipp: I disabled this to make cursors over links work again. -#if 0 + //case NS_MOUSE_ENTER: + //mouse enter doesn't work yet. Use move until then. case NS_MOUSE_MOVE: if (mTag == nsHTMLAtoms::a) { nsAutoString base, href, target; GetAttribute(nsString("href"), href); GetAttribute(nsString("target"), target); TriggerLink(aPresContext, base, href, target, PR_FALSE); - aEventStatus = nsEventStatus_eConsumeNoDefault; + aEventStatus = nsEventStatus_eConsumeDoDefault; } break; -#endif // XXX this doesn't seem to do anything yet case NS_MOUSE_EXIT: if (mTag == nsHTMLAtoms::a) { nsAutoString empty; TriggerLink(aPresContext, empty, empty, empty, PR_FALSE); - aEventStatus = nsEventStatus_eConsumeNoDefault; + aEventStatus = nsEventStatus_eConsumeDoDefault; } break; diff --git a/layout/html/base/src/nsHTMLTagContent.h b/layout/html/base/src/nsHTMLTagContent.h index 07c5bdbaee5f..511eece4d2ee 100644 --- a/layout/html/base/src/nsHTMLTagContent.h +++ b/layout/html/base/src/nsHTMLTagContent.h @@ -158,8 +158,9 @@ public: // nsIDOMEventReceiver interface NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, nsEventStatus& aEventStatus); // Utility routines for making attribute parsing easier diff --git a/layout/html/base/src/nsRootPart.cpp b/layout/html/base/src/nsRootPart.cpp index fd744fe7d387..9dee5b898b6b 100644 --- a/layout/html/base/src/nsRootPart.cpp +++ b/layout/html/base/src/nsRootPart.cpp @@ -32,6 +32,7 @@ #include "nsIRenderingContext.h" #include "nsIDeviceContext.h" #include "nsGUIEvent.h" +#include "nsDOMEvent.h" #include "nsStyleConsts.h" #include "nsIViewManager.h" #include "nsHTMLAtoms.h" @@ -155,13 +156,7 @@ NS_METHOD RootFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { - nsIEventStateManager *mManager; - - if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { - mManager->SetEventTarget((nsISupports*)mContent); - NS_RELEASE(mManager); - } - mContent->HandleDOMEvent(aPresContext, aEvent, nsnull, aEventStatus); + mContent->HandleDOMEvent(aPresContext, (nsEvent*)aEvent, nsnull, DOM_EVENT_INIT, aEventStatus); #if 0 if (aEventStatus != nsEventStatus_eConsumeNoDefault) { @@ -494,13 +489,7 @@ NS_METHOD RootContentFrame::HandleEvent(nsIPresContext& aPresContext, nsEventStatus& aEventStatus) { #if 0 - nsIEventStateManager *mManager; - - if (NS_OK == aPresContext.GetEventStateManager(&mManager)) { - mManager->SetEventTarget((nsISupports*)mContent); - NS_RELEASE(mManager); - } - mContent->HandleDOMEvent(aPresContext, aEvent, nsnull, aEventStatus); + mContent->HandleDOMEvent(aPresContext, (nsEvent*)aEvent, nsnull, DOM_EVENT_INIT, aEventStatus); #else nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); #endif @@ -544,12 +533,23 @@ NS_METHOD RootContentFrame::HandleEvent(nsIPresContext& aPresContext, if (mLastContent != mTargetContent) { if (nsnull != mLastContent) { //fire mouseout - /*mLastContent->HandleDOMEvent(*/ + nsEventStatus mStatus; + nsMouseEvent mEvent; + mEvent.eventStructType = NS_MOUSE_EVENT; + mEvent.message = NS_MOUSE_EXIT; + mLastContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus); + + NS_RELEASE(mLastContent); } - NS_IF_RELEASE(mLastContent); //fire mouseover - /*mTargetContent->HandleDOMEvent(*/ + nsEventStatus mStatus; + nsMouseEvent mEvent; + mEvent.eventStructType = NS_MOUSE_EVENT; + mEvent.message = NS_MOUSE_ENTER; + mTargetContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus); mStateManager->SetLastMouseOverContent(mTargetContent); + + NS_RELEASE(mStateManager); } } } @@ -564,9 +564,16 @@ NS_METHOD RootContentFrame::HandleEvent(nsIPresContext& aPresContext, mStateManager->GetLastMouseOverContent(&mLastContent); if (nsnull != mLastContent) { //fire mouseout - /*mLastContent->HandleDOMEvent(*/ + nsEventStatus mStatus; + nsMouseEvent mEvent; + mEvent.eventStructType = NS_MOUSE_EVENT; + mEvent.message = NS_MOUSE_EXIT; + mLastContent->HandleDOMEvent(aPresContext, &mEvent, nsnull, DOM_EVENT_INIT, mStatus); + mStateManager->SetLastMouseOverContent(nsnull); + + NS_RELEASE(mLastContent); } - NS_IF_RELEASE(mLastContent); + NS_RELEASE(mStateManager); } } break; @@ -588,9 +595,10 @@ public: nsIFrame*& aResult); NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, - nsEventStatus& aEventStatus); + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, + nsEventStatus& aEventStatus); NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject); @@ -626,11 +634,12 @@ RootPart::CreateFrame(nsIPresContext* aPresContext, nsresult RootPart::HandleDOMEvent(nsIPresContext& aPresContext, - nsGUIEvent* aEvent, - nsIDOMEvent* aDOMEvent, + nsEvent* aEvent, + nsIDOMEvent** aDOMEvent, + PRUint32 aFlags, nsEventStatus& aEventStatus) { - return mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aEventStatus); + return mDocument->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus); } nsresult diff --git a/widget/public/nsGUIEvent.h b/widget/public/nsGUIEvent.h index 972d95e96d53..d1fc4a53d06e 100644 --- a/widget/public/nsGUIEvent.h +++ b/widget/public/nsGUIEvent.h @@ -38,21 +38,30 @@ enum nsEventStatus { nsEventStatus_eConsumeDoDefault }; +/** + * General event + */ + +struct nsEvent { + /// See event struct types + PRUint8 eventStructType; + /// See GUI MESSAGES, + PRUint32 message; + /// in widget relative coordinates + nsPoint point; + /// elapsed time, in milliseconds, from the time the system was started to the time the message was created + PRUint32 time; +}; + /** * General graphic user interface event */ -struct nsGUIEvent { - /// See GUI MESSAGES, - PRUint32 message; +struct nsGUIEvent : public nsEvent { /// Originator of the event nsIWidget* widget; - /// in widget relative coordinates - nsISupports* widgetSupports; /// nsISupports of widget XXX remove the one above and rename this - nsPoint point; - /// elapsed time, in milliseconds, from the time the system was started to the time the message was created - PRUint32 time; + nsISupports* widgetSupports; /// Internal platform specific message. void* nativeMsg; }; @@ -132,8 +141,21 @@ struct nsMenuEvent : public nsGUIEvent { PRUint32 menuItem; }; - /** + * Event Struct Types + */ +#define NS_EVENT 1 +#define NS_GUI_EVENT 2 +#define NS_SIZE_EVENT 3 +#define NS_PAINT_EVENT 4 +#define NS_SCROLLBAR_EVENT 5 +#define NS_INPUT_EVENT 6 +#define NS_KEY_EVENT 7 +#define NS_MOUSE_EVENT 8 +#define NS_TOOLTIP_EVENT 9 +#define NS_MENU_EVENT 10 + + /** * GUI MESSAGES */ //@{ diff --git a/widget/src/motif/nsXtEventHandler.cpp b/widget/src/motif/nsXtEventHandler.cpp index 3f453e7255b6..9345fa2de3df 100644 --- a/widget/src/motif/nsXtEventHandler.cpp +++ b/widget/src/motif/nsXtEventHandler.cpp @@ -41,6 +41,7 @@ void nsXtWidget_InitNSEvent(XEvent * anXEv, { anEvent.message = aEventType; anEvent.widget = (nsWindow *) p; + anEvent.eventStructType = NS_GUI_EVENT; if (anXEv != NULL) { anEvent.point.x = anXEv->xbutton.x; @@ -64,6 +65,7 @@ void nsXtWidget_InitNSMouseEvent(XEvent * anXEv, anEvent.time = anXEv->xbutton.time; anEvent.isShift = anXEv->xbutton.state | ShiftMask; anEvent.isControl = anXEv->xbutton.state | ControlMask; + anEvent.eventStructType = NS_MOUSE_EVENT; } //anEvent.isAlt = GetKeyState(VK_LMENU) < 0 || GetKeyState(VK_RMENU) < 0; diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 9ccc2ffce506..d00edf35372d 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -267,7 +267,7 @@ void nsWindow::InitEvent(nsGUIEvent& event, PRUint32 aEventType, nsPoint* aPoint } event.time = ::GetMessageTime(); - event.message = aEventType; + event.message = aEventType; mLastPoint.x = event.point.x; mLastPoint.y = event.point.y; @@ -305,6 +305,7 @@ PRBool nsWindow::DispatchEvent(nsGUIEvent* event) PRBool nsWindow::DispatchStandardEvent(PRUint32 aMsg) { nsGUIEvent event; + event.eventStructType = NS_GUI_EVENT; InitEvent(event, aMsg); return(DispatchEvent(&event)); } @@ -1282,6 +1283,7 @@ PRBool nsWindow::OnKey(PRUint32 aEventType, PRUint32 aKeyCode) event.isShift = mIsShiftDown; event.isControl = mIsControlDown; event.isAlt = mIsAltDown; + event.eventStructType = NS_KEY_EVENT; return(DispatchEvent(&event)); } @@ -1305,6 +1307,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT if (wNotifyCode == 0) { // Menu selection nsMenuEvent event; event.menuItem = LOWORD(wParam); + event.eventStructType = NS_MENU_EVENT; InitEvent(event, NS_MENU_SELECTED); result = DispatchEvent(&event); } @@ -1328,6 +1331,7 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT nsTooltipEvent event; InitEvent(event, NS_SHOW_TOOLTIP); event.tipIndex = (PRUint32)wParam; + event.eventStructType = NS_TOOLTIP_EVENT; result = DispatchEvent(&event); } break; @@ -1708,6 +1712,7 @@ PRBool nsWindow::OnMove(PRInt32 aX, PRInt32 aY) InitEvent(event, NS_MOVE); event.point.x = aX; event.point.y = aY; + event.eventStructType = NS_GUI_EVENT; return DispatchEvent(&event); } @@ -1736,6 +1741,7 @@ PRBool nsWindow::OnPaint() ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); event.rect = ▭ + event.eventStructType = NS_PAINT_EVENT; ::EndPaint(mWnd, &ps); @@ -1777,6 +1783,7 @@ PRBool nsWindow::OnResize(nsRect &aWindowRect) nsSizeEvent event; InitEvent(event, NS_SIZE); event.windowSize = &aWindowRect; + event.eventStructType = NS_SIZE_EVENT; return(DispatchEvent(&event)); } @@ -1806,6 +1813,7 @@ PRBool nsWindow::DispatchMouseEvent(PRUint32 aEventType, nsPoint* aPoint) event.isAlt = GetKeyState(VK_LMENU) < 0 || GetKeyState(VK_RMENU) < 0; event.clickCount = (aEventType == NS_MOUSE_LEFT_DOUBLECLICK || aEventType == NS_MOUSE_LEFT_DOUBLECLICK)? 2:1; + event.eventStructType = NS_MOUSE_EVENT; // call the event callback if (nsnull != mEventCallback) {