From 10ffd04c8cac4ce7cae5d6ad25703d8a347f84a7 Mon Sep 17 00:00:00 2001 From: joki Date: Mon, 8 Jun 1998 00:57:15 +0000 Subject: [PATCH] Adding new event handling mechanism into raptor. --- content/base/public/nsIContent.h | 6 ++ content/base/public/nsIDocument.h | 7 ++ content/base/src/nsDocument.cpp | 100 ++++++++++++++++++ content/base/src/nsDocument.h | 17 ++- layout/Makefile | 2 +- layout/base/public/nsIContent.h | 6 ++ layout/base/public/nsIDocument.h | 7 ++ layout/base/src/nsDocument.cpp | 100 ++++++++++++++++++ layout/base/src/nsDocument.h | 17 ++- layout/base/src/nsFrame.cpp | 57 +++++----- layout/base/tests/TestContainerFrame.cpp | 2 + layout/build/Makefile | 1 + layout/build/makefile.win | 2 + layout/generic/nsHTMLContainerFrame.cpp | 91 +--------------- layout/generic/nsHTMLContainerFrame.h | 6 -- layout/html/base/src/nsHTMLContainerFrame.cpp | 91 +--------------- layout/html/base/src/nsHTMLContainerFrame.h | 6 -- layout/html/base/src/nsHTMLContent.cpp | 74 +++++++++++++ layout/html/base/src/nsHTMLContent.h | 17 ++- layout/html/base/src/nsHTMLTagContent.cpp | 84 +++++++++++++++ layout/html/base/src/nsHTMLTagContent.h | 10 ++ layout/html/base/src/nsRootPart.cpp | 14 +++ layout/html/tests/Makefile | 1 + layout/html/tests/makefile.win | 1 + layout/makefile.win | 2 +- 25 files changed, 498 insertions(+), 223 deletions(-) diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index f6d07b462875..128c507c2f61 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -21,6 +21,7 @@ #include #include "nslayout.h" #include "nsISupports.h" +#include "nsGUIEvent.h" class nsIAtom; class nsIContentDelegate; class nsIDocument; @@ -128,6 +129,11 @@ public: * any objects that it can reach. */ NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const = 0; + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) = 0; + }; #endif /* nsIContent_h___ */ diff --git a/content/base/public/nsIDocument.h b/content/base/public/nsIDocument.h index ae1bedca08f7..0debcc51ba8c 100644 --- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -21,6 +21,7 @@ #include "nslayout.h" #include "nsISupports.h" #include "nsIUnicharInputStream.h" +#include "nsGUIEvent.h" class nsIArena; class nsIContent; class nsIDocumentContainer; @@ -170,8 +171,14 @@ public: * Copies all text from the selection */ virtual void GetSelectionText(nsString & aText) = 0; + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) = 0; + }; + // XXX Belongs somewhere else extern NS_LAYOUT nsresult NS_NewHTMLDocument(nsIDocument** aInstancePtrResult); diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 0a06acb7f8c0..1298523beff8 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -24,6 +24,7 @@ #include "nsIStyleSheet.h" #include "nsIPresShell.h" #include "nsIDocumentObserver.h" +#include "nsEventListenerManager.h" #include "nsSelection.h" #include "nsIDOMText.h" @@ -38,6 +39,9 @@ static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); 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(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); NS_LAYOUT nsresult NS_NewPostData(nsIPostData* aPostData, nsIPostData** aInstancePtrResult) @@ -72,6 +76,7 @@ nsDocument::nsDocument() mParentDocument = nsnull; mRootContent = nsnull; mScriptObject = nsnull; + mListenerManager = nsnull; if (NS_OK != NS_NewSelection(&mSelection)) { printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n"); @@ -129,6 +134,16 @@ nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) AddRef(); return NS_OK; } + if (aIID.Equals(kIDOMEventCapturerIID)) { + *aInstancePtr = (void*)(nsIDOMEventCapturer*)this; + AddRef(); + return NS_OK; + } + if (aIID.Equals(kIDOMEventReceiverIID)) { + *aInstancePtr = (void*)(nsIDOMEventReceiver*)this; + AddRef(); + return NS_OK; + } static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); if (aIID.Equals(kISupportsIID)) { *aInstancePtr = (void*)(nsISupports*)(nsIDocument*)this; @@ -658,6 +673,91 @@ nsresult nsDocument::GetElementsByTagName(nsString &aTagname, nsIDOMNodeIterator return NS_ERROR_NOT_IMPLEMENTED; } +nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrResult) +{ + if (nsnull != mListenerManager) { + return mListenerManager->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult);; + } + else { + nsIEventListenerManager* l = new nsEventListenerManager(); + + if (nsnull == l) { + return NS_ERROR_OUT_OF_MEMORY; + } + + + if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) { + mListenerManager = l; + return NS_OK; + } + + return NS_ERROR_FAILURE; + } +} + +nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + //Capturing stage + + //Local handling stage + if (nsnull != mListenerManager) { + mListenerManager->HandleEvent(aPresContext, aEvent, aEventStatus); + } + + //Bubbling stage + /*Need to go to window here*/ + + return NS_OK; +} + +nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->AddEventListener(aListener, aIID); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->RemoveEventListener(aListener, aIID); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->CaptureEvent(aListener); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsDocument::ReleaseEvent(nsIDOMEventListener *aListener) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->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 c63284154df2..48590dfa9ffa 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -22,8 +22,10 @@ #include "nsVoidArray.h" #include "nsIDOMDocument.h" #include "nsIScriptObjectOwner.h" +#include "nsIDOMEventCapturer.h" class nsISelection; +class nsIEventListenerManager; class nsPostData : public nsIPostData { public: @@ -37,7 +39,7 @@ protected: }; // Base class for our document implementations -class nsDocument : public nsIDocument, public nsIDOMDocument, public nsIScriptObjectOwner { +class nsDocument : public nsIDocument, public nsIDOMDocument, public nsIScriptObjectOwner, public nsIDOMEventCapturer { public: NS_DECL_ISUPPORTS @@ -195,6 +197,18 @@ public: NS_IMETHOD CreateTreeIterator(nsIDOMNode **aNode, nsIDOMTreeIterator **aTreeIterator); NS_IMETHOD GetElementsByTagName(nsString &aTagname, nsIDOMNodeIterator **aIterator); + // nsIDOMEventCapturer interface + NS_IMETHOD CaptureEvent(nsIDOMEventListener *aListener); + NS_IMETHOD ReleaseEvent(nsIDOMEventListener *aListener); + NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); + NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); + + NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult); + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + protected: virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet); // subclass hook @@ -215,6 +229,7 @@ protected: nsVoidArray mStyleSheets; nsVoidArray mObservers; void* mScriptObject; + nsIEventListenerManager* mListenerManager; }; #endif /* nsDocument_h___ */ diff --git a/layout/Makefile b/layout/Makefile index 58defa2a298c..f85dc453da3a 100644 --- a/layout/Makefile +++ b/layout/Makefile @@ -17,7 +17,7 @@ DEPTH = .. -DIRS = base html build +DIRS = base html events build include $(DEPTH)/config/config.mk diff --git a/layout/base/public/nsIContent.h b/layout/base/public/nsIContent.h index f6d07b462875..128c507c2f61 100644 --- a/layout/base/public/nsIContent.h +++ b/layout/base/public/nsIContent.h @@ -21,6 +21,7 @@ #include #include "nslayout.h" #include "nsISupports.h" +#include "nsGUIEvent.h" class nsIAtom; class nsIContentDelegate; class nsIDocument; @@ -128,6 +129,11 @@ public: * any objects that it can reach. */ NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const = 0; + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) = 0; + }; #endif /* nsIContent_h___ */ diff --git a/layout/base/public/nsIDocument.h b/layout/base/public/nsIDocument.h index ae1bedca08f7..0debcc51ba8c 100644 --- a/layout/base/public/nsIDocument.h +++ b/layout/base/public/nsIDocument.h @@ -21,6 +21,7 @@ #include "nslayout.h" #include "nsISupports.h" #include "nsIUnicharInputStream.h" +#include "nsGUIEvent.h" class nsIArena; class nsIContent; class nsIDocumentContainer; @@ -170,8 +171,14 @@ public: * Copies all text from the selection */ virtual void GetSelectionText(nsString & aText) = 0; + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) = 0; + }; + // XXX Belongs somewhere else extern NS_LAYOUT nsresult NS_NewHTMLDocument(nsIDocument** aInstancePtrResult); diff --git a/layout/base/src/nsDocument.cpp b/layout/base/src/nsDocument.cpp index 0a06acb7f8c0..1298523beff8 100644 --- a/layout/base/src/nsDocument.cpp +++ b/layout/base/src/nsDocument.cpp @@ -24,6 +24,7 @@ #include "nsIStyleSheet.h" #include "nsIPresShell.h" #include "nsIDocumentObserver.h" +#include "nsEventListenerManager.h" #include "nsSelection.h" #include "nsIDOMText.h" @@ -38,6 +39,9 @@ static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID); static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); 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(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID); NS_LAYOUT nsresult NS_NewPostData(nsIPostData* aPostData, nsIPostData** aInstancePtrResult) @@ -72,6 +76,7 @@ nsDocument::nsDocument() mParentDocument = nsnull; mRootContent = nsnull; mScriptObject = nsnull; + mListenerManager = nsnull; if (NS_OK != NS_NewSelection(&mSelection)) { printf("*************** Error: nsDocument::nsDocument - Creation of Selection failed!\n"); @@ -129,6 +134,16 @@ nsresult nsDocument::QueryInterface(REFNSIID aIID, void** aInstancePtr) AddRef(); return NS_OK; } + if (aIID.Equals(kIDOMEventCapturerIID)) { + *aInstancePtr = (void*)(nsIDOMEventCapturer*)this; + AddRef(); + return NS_OK; + } + if (aIID.Equals(kIDOMEventReceiverIID)) { + *aInstancePtr = (void*)(nsIDOMEventReceiver*)this; + AddRef(); + return NS_OK; + } static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); if (aIID.Equals(kISupportsIID)) { *aInstancePtr = (void*)(nsISupports*)(nsIDocument*)this; @@ -658,6 +673,91 @@ nsresult nsDocument::GetElementsByTagName(nsString &aTagname, nsIDOMNodeIterator return NS_ERROR_NOT_IMPLEMENTED; } +nsresult nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrResult) +{ + if (nsnull != mListenerManager) { + return mListenerManager->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult);; + } + else { + nsIEventListenerManager* l = new nsEventListenerManager(); + + if (nsnull == l) { + return NS_ERROR_OUT_OF_MEMORY; + } + + + if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) { + mListenerManager = l; + return NS_OK; + } + + return NS_ERROR_FAILURE; + } +} + +nsresult nsDocument::HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + //Capturing stage + + //Local handling stage + if (nsnull != mListenerManager) { + mListenerManager->HandleEvent(aPresContext, aEvent, aEventStatus); + } + + //Bubbling stage + /*Need to go to window here*/ + + return NS_OK; +} + +nsresult nsDocument::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->AddEventListener(aListener, aIID); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsDocument::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->RemoveEventListener(aListener, aIID); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsDocument::CaptureEvent(nsIDOMEventListener *aListener) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->CaptureEvent(aListener); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsDocument::ReleaseEvent(nsIDOMEventListener *aListener) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->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 c63284154df2..48590dfa9ffa 100644 --- a/layout/base/src/nsDocument.h +++ b/layout/base/src/nsDocument.h @@ -22,8 +22,10 @@ #include "nsVoidArray.h" #include "nsIDOMDocument.h" #include "nsIScriptObjectOwner.h" +#include "nsIDOMEventCapturer.h" class nsISelection; +class nsIEventListenerManager; class nsPostData : public nsIPostData { public: @@ -37,7 +39,7 @@ protected: }; // Base class for our document implementations -class nsDocument : public nsIDocument, public nsIDOMDocument, public nsIScriptObjectOwner { +class nsDocument : public nsIDocument, public nsIDOMDocument, public nsIScriptObjectOwner, public nsIDOMEventCapturer { public: NS_DECL_ISUPPORTS @@ -195,6 +197,18 @@ public: NS_IMETHOD CreateTreeIterator(nsIDOMNode **aNode, nsIDOMTreeIterator **aTreeIterator); NS_IMETHOD GetElementsByTagName(nsString &aTagname, nsIDOMNodeIterator **aIterator); + // nsIDOMEventCapturer interface + NS_IMETHOD CaptureEvent(nsIDOMEventListener *aListener); + NS_IMETHOD ReleaseEvent(nsIDOMEventListener *aListener); + NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); + NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); + + NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult); + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + protected: virtual void AddStyleSheetToSet(nsIStyleSheet* aSheet, nsIStyleSet* aSet); // subclass hook @@ -215,6 +229,7 @@ protected: nsVoidArray mStyleSheets; nsVoidArray mObservers; void* mScriptObject; + nsIEventListenerManager* mListenerManager; }; #endif /* nsDocument_h___ */ diff --git a/layout/base/src/nsFrame.cpp b/layout/base/src/nsFrame.cpp index c03d5342d37d..44170dbf4428 100644 --- a/layout/base/src/nsFrame.cpp +++ b/layout/base/src/nsFrame.cpp @@ -532,42 +532,47 @@ NS_METHOD nsFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { -#if DO_SELECTION + aEventStatus = nsEventStatus_eIgnore; + + mContent->HandleDOMEvent(aPresContext, aEvent, aEventStatus); - if (aEvent->message == NS_MOUSE_MOVE && mDoingSelection || - aEvent->message == NS_MOUSE_LEFT_BUTTON_UP || - aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) { - } else { - aEventStatus = nsEventStatus_eIgnore; - return NS_OK; - } - if (gSelectionDebug) printf("Message: %d-------------------------------------------------------------\n",aEvent->message); +#if DO_SELECTION - - if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) { - if (mDoingSelection) { - //mEndSelect = 0; - HandleRelease(aPresContext, aEvent, aEventStatus, this); + if(nsEventStatus_eIgnore == aEventStatus) { + if (aEvent->message == NS_MOUSE_MOVE && mDoingSelection || + aEvent->message == NS_MOUSE_LEFT_BUTTON_UP || + aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) { + } else { + aEventStatus = nsEventStatus_eIgnore; + return NS_OK; } - } else if (aEvent->message == NS_MOUSE_MOVE) { - mDidDrag = PR_TRUE; + if (gSelectionDebug) printf("Message: %d-------------------------------------------------------------\n",aEvent->message); - //if (gSelectionDebug) printf("HandleEvent(Drag)::mSelectionRange %s\n", mSelectionRange->ToString()); - HandleDrag(aPresContext, aEvent, aEventStatus, this); - if (gSelectionDebug) printf("HandleEvent(Drag)::mSelectionRange %s\n", mSelectionRange->ToString()); - } else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) { - nsIContent * content; - GetContent(content); - BuildContentList(content); + if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) { + if (mDoingSelection) { + //mEndSelect = 0; + HandleRelease(aPresContext, aEvent, aEventStatus, this); + } + } else if (aEvent->message == NS_MOUSE_MOVE) { + mDidDrag = PR_TRUE; - NS_RELEASE(content); + //if (gSelectionDebug) printf("HandleEvent(Drag)::mSelectionRange %s\n", mSelectionRange->ToString()); + HandleDrag(aPresContext, aEvent, aEventStatus, this); + if (gSelectionDebug) printf("HandleEvent(Drag)::mSelectionRange %s\n", mSelectionRange->ToString()); - HandlePress(aPresContext, aEvent, aEventStatus, this); + } else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) { + nsIContent * content; + GetContent(content); + BuildContentList(content); + + NS_RELEASE(content); + + HandlePress(aPresContext, aEvent, aEventStatus, this); + } } #endif - aEventStatus = nsEventStatus_eIgnore; return NS_OK; } diff --git a/layout/base/tests/TestContainerFrame.cpp b/layout/base/tests/TestContainerFrame.cpp index 19f781fcee44..aa5bb3957fbf 100644 --- a/layout/base/tests/TestContainerFrame.cpp +++ b/layout/base/tests/TestContainerFrame.cpp @@ -82,6 +82,8 @@ 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, nsEventStatus& aEventStatus) + {return NS_OK;} NS_DECL_ISUPPORTS diff --git a/layout/build/Makefile b/layout/build/Makefile index c04cbbe33e3f..667ca5869dbf 100644 --- a/layout/build/Makefile +++ b/layout/build/Makefile @@ -36,5 +36,6 @@ LOBJS = \ $(DIST)/lib/libraptorhtmlforms_s.a \ $(DIST)/lib/libraptorhtmlstyle_s.a \ $(DIST)/lib/libraptorhtmltable_s.a \ + $(DIST)/lib/libraptorevents_s.a \ include $(DEPTH)/config/rules.mk diff --git a/layout/build/makefile.win b/layout/build/makefile.win index 531100917114..5db17e6f42d1 100644 --- a/layout/build/makefile.win +++ b/layout/build/makefile.win @@ -39,6 +39,7 @@ MISCDEP = \ $(DIST)\lib\raptorhtmlforms_s.lib \ $(DIST)\lib\raptorhtmlstyle_s.lib \ $(DIST)\lib\raptorhtmltable_s.lib \ + $(DIST)\lib\raptorevents_s.lib \ $(DIST)\lib\xpcom32.lib \ $(DIST)\lib\raptorbase.lib \ $(DIST)\lib\raptorgfx.lib \ @@ -62,6 +63,7 @@ LLIBS= \ $(DIST)\lib\raptorhtmlforms_s.lib \ $(DIST)\lib\raptorhtmlstyle_s.lib \ $(DIST)\lib\raptorhtmltable_s.lib \ + $(DIST)\lib\raptorevents_s.lib \ $(DIST)\lib\xpcom32.lib \ $(DIST)\lib\raptorbase.lib \ $(DIST)\lib\raptorgfx.lib \ diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp index c519c597ae96..d350a819a9a3 100644 --- a/layout/generic/nsHTMLContainerFrame.cpp +++ b/layout/generic/nsHTMLContainerFrame.cpp @@ -89,100 +89,11 @@ NS_METHOD nsHTMLContainerFrame::Paint(nsIPresContext& aPresContext, return NS_OK; } -void nsHTMLContainerFrame::TriggerLink(nsIPresContext& aPresContext, - const nsString& aBase, - const nsString& aURLSpec, - const nsString& aTargetSpec, - PRBool aClick) -{ - nsILinkHandler* handler; - if (NS_OK == aPresContext.GetLinkHandler(&handler)) { - // Resolve url to an absolute url - nsIURL* docURL = nsnull; - nsIDocument* doc = nsnull; - mContent->GetDocument(doc); - if (nsnull != doc) { - docURL = doc->GetDocumentURL(); - NS_RELEASE(doc); - } - - nsAutoString absURLSpec; - nsresult rv = NS_MakeAbsoluteURL(docURL, aBase, aURLSpec, absURLSpec); - if (nsnull != docURL) { - NS_RELEASE(docURL); - } - - // Now pass on absolute url to the click handler - if (aClick) { - handler->OnLinkClick(this, absURLSpec, aTargetSpec); - } - else { - handler->OnOverLink(this, absURLSpec, aTargetSpec); - } - } -} - NS_METHOD nsHTMLContainerFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { - aEventStatus = nsEventStatus_eIgnore; - switch (aEvent->message) { - case NS_MOUSE_LEFT_BUTTON_UP: - if (nsEventStatus_eIgnore == - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus)) { - // If our child didn't take the click then since we are an - // anchor, we take the click. - nsIAtom* tag = mContent->GetTag(); - if (tag == nsHTMLAtoms::a) { - nsAutoString base, href, target; - mContent->GetAttribute("href", href); - mContent->GetAttribute("target", target); - TriggerLink(aPresContext, base, href, target, PR_TRUE); - aEventStatus = nsEventStatus_eConsumeNoDefault; - } - NS_IF_RELEASE(tag); - } - break; - - case NS_MOUSE_RIGHT_BUTTON_DOWN: - // XXX Bring up a contextual menu provided by the application - break; - - case NS_MOUSE_MOVE: - if (nsEventStatus_eIgnore == - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus)) { - nsIAtom* tag = mContent->GetTag(); - if (tag == nsHTMLAtoms::a) { - nsAutoString base, href, target; - mContent->GetAttribute("href", href); - mContent->GetAttribute("target", target); - TriggerLink(aPresContext, base, href, target, PR_FALSE); - aEventStatus = nsEventStatus_eConsumeNoDefault; - } - NS_IF_RELEASE(tag); - } - break; - - // XXX this doesn't seem to do anything yet - case NS_MOUSE_EXIT: - if (nsEventStatus_eIgnore == - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus)) { - nsIAtom* tag = mContent->GetTag(); - if (tag == nsHTMLAtoms::a) { - nsAutoString empty; - TriggerLink(aPresContext, empty, empty, empty, PR_FALSE); - aEventStatus = nsEventStatus_eConsumeNoDefault; - } - NS_IF_RELEASE(tag); - } - break; - - default: - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); - break; - } - return NS_OK; + return nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } NS_METHOD nsHTMLContainerFrame::GetCursorAt(nsIPresContext& aPresContext, diff --git a/layout/generic/nsHTMLContainerFrame.h b/layout/generic/nsHTMLContainerFrame.h index e68e03b5c45b..aefa2feb007e 100644 --- a/layout/generic/nsHTMLContainerFrame.h +++ b/layout/generic/nsHTMLContainerFrame.h @@ -56,12 +56,6 @@ protected: virtual PRIntn GetSkipSides() const = 0; - void TriggerLink(nsIPresContext& aPresContext, - const nsString& aBase, - const nsString& aURLSpec, - const nsString& aTargetSpec, - PRBool aClick); - nsresult CreateFrameFor(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aStyleContext, diff --git a/layout/html/base/src/nsHTMLContainerFrame.cpp b/layout/html/base/src/nsHTMLContainerFrame.cpp index c519c597ae96..d350a819a9a3 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -89,100 +89,11 @@ NS_METHOD nsHTMLContainerFrame::Paint(nsIPresContext& aPresContext, return NS_OK; } -void nsHTMLContainerFrame::TriggerLink(nsIPresContext& aPresContext, - const nsString& aBase, - const nsString& aURLSpec, - const nsString& aTargetSpec, - PRBool aClick) -{ - nsILinkHandler* handler; - if (NS_OK == aPresContext.GetLinkHandler(&handler)) { - // Resolve url to an absolute url - nsIURL* docURL = nsnull; - nsIDocument* doc = nsnull; - mContent->GetDocument(doc); - if (nsnull != doc) { - docURL = doc->GetDocumentURL(); - NS_RELEASE(doc); - } - - nsAutoString absURLSpec; - nsresult rv = NS_MakeAbsoluteURL(docURL, aBase, aURLSpec, absURLSpec); - if (nsnull != docURL) { - NS_RELEASE(docURL); - } - - // Now pass on absolute url to the click handler - if (aClick) { - handler->OnLinkClick(this, absURLSpec, aTargetSpec); - } - else { - handler->OnOverLink(this, absURLSpec, aTargetSpec); - } - } -} - NS_METHOD nsHTMLContainerFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { - aEventStatus = nsEventStatus_eIgnore; - switch (aEvent->message) { - case NS_MOUSE_LEFT_BUTTON_UP: - if (nsEventStatus_eIgnore == - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus)) { - // If our child didn't take the click then since we are an - // anchor, we take the click. - nsIAtom* tag = mContent->GetTag(); - if (tag == nsHTMLAtoms::a) { - nsAutoString base, href, target; - mContent->GetAttribute("href", href); - mContent->GetAttribute("target", target); - TriggerLink(aPresContext, base, href, target, PR_TRUE); - aEventStatus = nsEventStatus_eConsumeNoDefault; - } - NS_IF_RELEASE(tag); - } - break; - - case NS_MOUSE_RIGHT_BUTTON_DOWN: - // XXX Bring up a contextual menu provided by the application - break; - - case NS_MOUSE_MOVE: - if (nsEventStatus_eIgnore == - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus)) { - nsIAtom* tag = mContent->GetTag(); - if (tag == nsHTMLAtoms::a) { - nsAutoString base, href, target; - mContent->GetAttribute("href", href); - mContent->GetAttribute("target", target); - TriggerLink(aPresContext, base, href, target, PR_FALSE); - aEventStatus = nsEventStatus_eConsumeNoDefault; - } - NS_IF_RELEASE(tag); - } - break; - - // XXX this doesn't seem to do anything yet - case NS_MOUSE_EXIT: - if (nsEventStatus_eIgnore == - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus)) { - nsIAtom* tag = mContent->GetTag(); - if (tag == nsHTMLAtoms::a) { - nsAutoString empty; - TriggerLink(aPresContext, empty, empty, empty, PR_FALSE); - aEventStatus = nsEventStatus_eConsumeNoDefault; - } - NS_IF_RELEASE(tag); - } - break; - - default: - nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); - break; - } - return NS_OK; + return nsContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } NS_METHOD nsHTMLContainerFrame::GetCursorAt(nsIPresContext& aPresContext, diff --git a/layout/html/base/src/nsHTMLContainerFrame.h b/layout/html/base/src/nsHTMLContainerFrame.h index e68e03b5c45b..aefa2feb007e 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.h +++ b/layout/html/base/src/nsHTMLContainerFrame.h @@ -56,12 +56,6 @@ protected: virtual PRIntn GetSkipSides() const = 0; - void TriggerLink(nsIPresContext& aPresContext, - const nsString& aBase, - const nsString& aURLSpec, - const nsString& aTargetSpec, - PRBool aClick); - nsresult CreateFrameFor(nsIPresContext* aPresContext, nsIContent* aContent, nsIStyleContext* aStyleContext, diff --git a/layout/html/base/src/nsHTMLContent.cpp b/layout/html/base/src/nsHTMLContent.cpp index 7eb75a0e6b39..858c4d29e311 100644 --- a/layout/html/base/src/nsHTMLContent.cpp +++ b/layout/html/base/src/nsHTMLContent.cpp @@ -26,6 +26,8 @@ #include "nsISupportsArray.h" #include "nsCRT.h" #include "nsIDocument.h" +#include "nsIEventListenerManager.h" +#include "nsEventListenerManager.h" #include "nsISizeOfHandler.h" static NS_DEFINE_IID(kIContentDelegateIID, NS_ICONTENTDELEGATE_IID); @@ -33,6 +35,8 @@ static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID); static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_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 nsIContentDelegate* gContentDelegate; @@ -132,6 +136,8 @@ nsHTMLContent::nsHTMLContent() gContentDelegate = new ContentDelegate(); } + mListenerManager = nsnull; + // Add a reference to the shared content delegate object NS_ADDREF(gContentDelegate); } @@ -184,6 +190,11 @@ nsresult nsHTMLContent::QueryInterface(const nsIID& aIID, AddRef(); return NS_OK; } + if (aIID.Equals(kIDOMEventReceiverIID)) { + *aInstancePtrResult = (void*)(nsIDOMEventReceiver*)this; + AddRef(); + return NS_OK; + } return NS_NOINTERFACE; } @@ -533,6 +544,69 @@ nsresult nsHTMLContent::RemoveChild(nsIDOMNode *oldChild) return NS_ERROR_FAILURE; } +nsresult nsHTMLContent::GetListenerManager(nsIEventListenerManager **aInstancePtrResult) +{ + if (nsnull != mListenerManager) { + return mListenerManager->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult);; + } + else { + nsIEventListenerManager* l = new nsEventListenerManager(); + + if (nsnull == l) { + return NS_ERROR_OUT_OF_MEMORY; + } + + + if (NS_OK == l->QueryInterface(kIEventListenerManagerIID, (void**) aInstancePtrResult)) { + mListenerManager = l; + return NS_OK; + } + + return NS_ERROR_FAILURE; + } +} + +nsresult nsHTMLContent::AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->AddEventListener(aListener, aIID); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsHTMLContent::RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID) +{ + nsIEventListenerManager *manager; + + if (NS_OK == GetListenerManager(&manager)) { + manager->RemoveEventListener(aListener, aIID); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsHTMLContent::HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + //Capturing stage + + //Local handling stage + if (nsnull != mListenerManager) { + mListenerManager->HandleEvent(aPresContext, aEvent, aEventStatus); + } + + //Bubbling stage + if (mParent != nsnull) { + return mParent->HandleDOMEvent(aPresContext, aEvent, aEventStatus); + } + + return NS_OK; +} + // XXX i18n: this is wrong (?) because we need to know the outgoing // character set (I think) void diff --git a/layout/html/base/src/nsHTMLContent.h b/layout/html/base/src/nsHTMLContent.h index 38f6e778016e..fd2055c277b1 100644 --- a/layout/html/base/src/nsHTMLContent.h +++ b/layout/html/base/src/nsHTMLContent.h @@ -21,6 +21,9 @@ #include "nsIHTMLContent.h" #include "nsIDOMNode.h" #include "nsIScriptObjectOwner.h" +#include "nsIDOMEventReceiver.h" +#include "nsGUIEvent.h" +class nsIEventListenerManager; class nsIArena; class nsIAtom; @@ -29,7 +32,7 @@ class nsIAtom; * allocation from the malloc heap as well as from an arena. Note * that instances of this object are created with zero'd memory. */ -class nsHTMLContent : public nsIHTMLContent, public nsIDOMNode, public nsIScriptObjectOwner { +class nsHTMLContent : public nsIHTMLContent, public nsIDOMNode, public nsIScriptObjectOwner, public nsIDOMEventReceiver { public: /** * This new method allocates memory from the standard malloc heap @@ -126,6 +129,14 @@ public: NS_IMETHOD ReplaceChild(nsIDOMNode *newChild, nsIDOMNode *oldChild); NS_IMETHOD RemoveChild(nsIDOMNode *oldChild); + // nsIDOMEventReceiver interface + NS_IMETHOD AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); + NS_IMETHOD RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID); + + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + protected: nsHTMLContent(); virtual ~nsHTMLContent(); @@ -137,6 +148,10 @@ protected: nsIDocument* mDocument; nsIContent* mParent; void* mScriptObject; + + nsresult GetListenerManager(nsIEventListenerManager** aInstancePtrResult); + + nsIEventListenerManager* mListenerManager; }; #endif /* nsHTMLContent_h___ */ diff --git a/layout/html/base/src/nsHTMLTagContent.cpp b/layout/html/base/src/nsHTMLTagContent.cpp index 23ee9b5bbab2..f927335e901c 100644 --- a/layout/html/base/src/nsHTMLTagContent.cpp +++ b/layout/html/base/src/nsHTMLTagContent.cpp @@ -26,6 +26,9 @@ #include "nsString.h" #include "prprf.h" #include "nsDOMAttributes.h" +#include "nsILinkHandler.h" +#include "nsIPresContext.h" +#include "nsIURL.h" #include "nsICSSParser.h" #include "nsISupportsArray.h" #include "nsISizeOfHandler.h" @@ -534,6 +537,87 @@ nsresult nsHTMLTagContent::GetElementsByTagName(nsString &aName,nsIDOMNodeIterat return NS_ERROR_NOT_IMPLEMENTED; } +void nsHTMLTagContent::TriggerLink(nsIPresContext& aPresContext, + const nsString& aBase, + const nsString& aURLSpec, + const nsString& aTargetSpec, + PRBool aClick) +{ + nsILinkHandler* handler; + if (NS_OK == aPresContext.GetLinkHandler(&handler)) { + // Resolve url to an absolute url + nsIURL* docURL = nsnull; + nsIDocument* doc; + if (NS_OK == GetDocument(doc)) { + docURL = doc->GetDocumentURL(); + NS_RELEASE(doc); + } + + nsAutoString absURLSpec; + nsresult rv = NS_MakeAbsoluteURL(docURL, aBase, aURLSpec, absURLSpec); + if (nsnull != docURL) { + NS_RELEASE(docURL); + } + + // Now pass on absolute url to the click handler + if (aClick) { + handler->OnLinkClick(nsnull, absURLSpec, aTargetSpec); + } + else { + handler->OnOverLink(nsnull, absURLSpec, aTargetSpec); + } + } +} + +nsresult nsHTMLTagContent::HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + nsresult ret = NS_OK; + + ret = nsHTMLContent::HandleDOMEvent(aPresContext, aEvent, aEventStatus); + + if (NS_OK == ret && nsEventStatus_eIgnore == aEventStatus) { + switch (aEvent->message) { + case NS_MOUSE_LEFT_BUTTON_UP: + if (mTag == nsHTMLAtoms::a) { + nsAutoString base, href, target; + GetAttribute("href", href); + GetAttribute("target", target); + TriggerLink(aPresContext, base, href, target, PR_TRUE); + aEventStatus = nsEventStatus_eConsumeNoDefault; + } + break; + + case NS_MOUSE_RIGHT_BUTTON_DOWN: + // XXX Bring up a contextual menu provided by the application + break; + + case NS_MOUSE_MOVE: + if (mTag == nsHTMLAtoms::a) { + nsAutoString base, href, target; + GetAttribute("href", href); + GetAttribute("target", target); + TriggerLink(aPresContext, base, href, target, PR_FALSE); + aEventStatus = nsEventStatus_eConsumeNoDefault; + } + break; + + // 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; + } + break; + + default: + break; + } + } + return ret; +} //---------------------------------------------------------------------- diff --git a/layout/html/base/src/nsHTMLTagContent.h b/layout/html/base/src/nsHTMLTagContent.h index f49bfacb9940..87574051e4e2 100644 --- a/layout/html/base/src/nsHTMLTagContent.h +++ b/layout/html/base/src/nsHTMLTagContent.h @@ -114,6 +114,10 @@ public: NS_IMETHOD GetElementsByTagName(nsString &aName,nsIDOMNodeIterator **aIterator); NS_IMETHOD Normalize(); + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + // Utility routines for making attribute parsing easier struct EnumTable { @@ -203,6 +207,12 @@ protected: nsHTMLValue& aValue, nsString& aResult) const; + void TriggerLink(nsIPresContext& aPresContext, + const nsString& aBase, + const nsString& aURLSpec, + const nsString& aTargetSpec, + PRBool aClick); + nsIAtom* mTag; nsIHTMLAttributes* mAttributes; }; diff --git a/layout/html/base/src/nsRootPart.cpp b/layout/html/base/src/nsRootPart.cpp index cc414b5788bf..744df52e5c75 100644 --- a/layout/html/base/src/nsRootPart.cpp +++ b/layout/html/base/src/nsRootPart.cpp @@ -145,6 +145,8 @@ NS_METHOD RootFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { + mContent->HandleDOMEvent(aPresContext, aEvent, aEventStatus); + switch (aEvent->message) { case NS_MOUSE_MOVE: case NS_MOUSE_ENTER: @@ -453,6 +455,10 @@ public: nsIStyleContext* aStyleContext, nsIFrame*& aResult); + NS_IMETHOD HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); + protected: virtual ~RootPart(); }; @@ -483,6 +489,14 @@ RootPart::CreateFrame(nsIPresContext* aPresContext, return NS_OK; } +nsresult +RootPart::HandleDOMEvent(nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + return mDocument->HandleDOMEvent(aPresContext, aEvent, aEventStatus); +} + nsresult NS_NewRootPart(nsIHTMLContent** aInstancePtrResult, nsIDocument* aDocument) diff --git a/layout/html/tests/Makefile b/layout/html/tests/Makefile index 92a3b39c3893..87124f2b9875 100644 --- a/layout/html/tests/Makefile +++ b/layout/html/tests/Makefile @@ -37,6 +37,7 @@ EX_LIBS = \ $(DIST)/lib/libraptorlayout_s.a \ $(DIST)/lib/libraptorgfx.a \ $(DIST)/lib/libraptorbase.a \ + $(DIST)/lib/libraptorevents.a \ $(DIST)/lib/libxpcom.a \ $(DIST)/lib/libplc21.a \ $(DIST)/lib/libplds21.a \ diff --git a/layout/html/tests/makefile.win b/layout/html/tests/makefile.win index 7f20486f042f..6b8f440ac7d6 100644 --- a/layout/html/tests/makefile.win +++ b/layout/html/tests/makefile.win @@ -43,6 +43,7 @@ LLIBS= \ $(DIST)\lib\raptorlayout_s.lib \ $(DIST)\lib\raptorgfx.lib \ $(DIST)\lib\raptorbase.lib \ + $(DIST)\lib\raptorevents_s.lib \ $(DIST)\lib\img3240.lib \ $(DIST)\lib\util.lib \ $(DIST)\lib\xpcom32.lib \ diff --git a/layout/makefile.win b/layout/makefile.win index 1f5f6acfbfe3..b5b1b618d1dd 100644 --- a/layout/makefile.win +++ b/layout/makefile.win @@ -17,6 +17,6 @@ DEPTH=.. -DIRS=base html build +DIRS=base html events build include <$(DEPTH)\layout\config\rules.mak>