Added mouse DOM listener to listen for context menu events and notify the embedding client. b=48270 a=valeski

This commit is contained in:
locka%iol.ie 2000-08-16 08:51:58 +00:00
parent 8dc8cb2777
commit 9ea803e364
2 changed files with 281 additions and 30 deletions

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
@ -30,8 +30,18 @@
#include "nsHTMLReflowState.h"
// Interfaces needed to be included
#include "nsIContextMenuListener.h"
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentType.h"
#include "nsIDOMElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMHTMLElement.h"
#include "nsIPresShell.h"
// CIDs
@ -40,7 +50,8 @@
//*** nsDocShellTreeOwner: Object Management
//*****************************************************************************
nsDocShellTreeOwner::nsDocShellTreeOwner() : mWebBrowser(nsnull),
nsDocShellTreeOwner::nsDocShellTreeOwner() :
mWebBrowser(nsnull),
mTreeOwner(nsnull),
mPrimaryContentShell(nsnull),
mWebBrowserChrome(nsnull),
@ -63,11 +74,14 @@ NS_IMPL_ADDREF(nsDocShellTreeOwner)
NS_IMPL_RELEASE(nsDocShellTreeOwner)
NS_INTERFACE_MAP_BEGIN(nsDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
NS_INTERFACE_MAP_ENTRY(nsICDocShellTreeOwner)
NS_INTERFACE_MAP_END
//*****************************************************************************
@ -138,9 +152,9 @@ NS_IMETHODIMP nsDocShellTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem**
{
NS_ENSURE_ARG_POINTER(aShell);
if (mTreeOwner)
if(mTreeOwner)
return mTreeOwner->GetPrimaryContentShell(aShell);
*aShell = (mPrimaryContentShell ? mPrimaryContentShell : mWebBrowser->mDocShellAsItem.get());
NS_IF_ADDREF(*aShell);
@ -426,15 +440,20 @@ nsDocShellTreeOwner::OnProgressChange(nsIWebProgress* aProgress,
PRInt32 aCurTotalProgress,
PRInt32 aMaxTotalProgress)
{
if(!mOwnerProgressListener)
return NS_OK;
// In the absence of DOM document creation event, this method is the
// most convenient place to install the mouse listener on the
// DOM document.
AddMouseListener();
if(!mOwnerProgressListener)
return NS_OK;
return mOwnerProgressListener->OnProgressChange(aProgress,
aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress);
return mOwnerProgressListener->OnProgressChange(aProgress,
aRequest,
aCurSelfProgress,
aMaxSelfProgress,
aCurTotalProgress,
aMaxTotalProgress);
}
NS_IMETHODIMP
@ -484,7 +503,7 @@ nsDocShellTreeOwner::OnStatusChange(nsIWebProgress* aWebProgress,
void nsDocShellTreeOwner::WebBrowser(nsWebBrowser* aWebBrowser)
{
mWebBrowser = aWebBrowser;
mWebBrowser = aWebBrowser;
}
nsWebBrowser* nsDocShellTreeOwner::WebBrowser()
@ -536,3 +555,198 @@ NS_IMETHODIMP nsDocShellTreeOwner::SetWebBrowserChrome(nsIWebBrowserChrome* aWeb
}
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP nsDocShellTreeOwner::AddMouseListener()
{
// Clear out the old listener
RemoveMouseListener();
NS_ENSURE_TRUE(mWebBrowser, NS_ERROR_FAILURE);
// Get the DOM document
nsCOMPtr<nsIDOMDocument> domDocument;
mWebBrowser->GetDocument(getter_AddRefs(domDocument));
if (domDocument == nsnull)
{
return NS_ERROR_FAILURE;
}
// Subscribe to mouse events
nsCOMPtr<nsIDOMEventReceiver> eventReceiver;
domDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(eventReceiver));
if (eventReceiver)
{
nsIDOMMouseListener *pListener = NS_STATIC_CAST(nsIDOMMouseListener *, this);
eventReceiver->AddEventListenerByIID(pListener, NS_GET_IID(nsIDOMMouseListener));
}
mLastDOMDocument = domDocument;
return NS_OK;
}
NS_IMETHODIMP nsDocShellTreeOwner::RemoveMouseListener()
{
// Unsubscribe from mouse events
if (mLastDOMDocument)
{
nsCOMPtr<nsIDOMEventReceiver> eventReceiver;
mLastDOMDocument->QueryInterface(NS_GET_IID(nsIDOMEventReceiver), getter_AddRefs(eventReceiver));
if (eventReceiver)
{
nsIDOMMouseListener *pListener = NS_STATIC_CAST(nsIDOMMouseListener *, this);
eventReceiver->RemoveEventListenerByIID(pListener, NS_GET_IID(nsIDOMMouseListener));
}
mLastDOMDocument = nsnull;
}
return NS_OK;
}
nsresult nsDocShellTreeOwner::HandleEvent(nsIDOMEvent* aEvent)
{
return NS_OK;
}
nsresult nsDocShellTreeOwner::MouseDown(nsIDOMEvent* aMouseEvent)
{
// Don't bother going any further if no one is interested in context menu events
nsCOMPtr<nsIContextMenuListener> menuListener(do_QueryInterface(mTreeOwner));
if (!menuListener)
{
return NS_OK;
}
nsCOMPtr<nsIDOMMouseEvent> mouseEvent (do_QueryInterface(aMouseEvent));
if (!mouseEvent)
{
return NS_OK;
}
// Test for right mouse button click
PRUint16 buttonNumber;
nsresult res = mouseEvent->GetButton(&buttonNumber);
if (NS_FAILED(res))
{
return res;
}
if (buttonNumber != 3) // 3 is the magic number
{
return NS_OK;
}
nsCOMPtr<nsIDOMEventTarget> targetNode;
res = aMouseEvent->GetTarget(getter_AddRefs(targetNode));
if (NS_FAILED(res))
{
return res;
}
if (!targetNode)
{
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(targetNode);
if (!node)
{
return NS_OK;
}
// Find the first node to be an element starting with this node and
// working up through its parents.
PRUint32 flags = nsIContextMenuListener::CONTEXT_NONE;
nsCOMPtr<nsIDOMHTMLElement> element;
do {
PRUint16 type;
node->GetNodeType(&type);
// XXX test for selected text
element = do_QueryInterface(node);
if (element)
{
nsAutoString tag;
element->GetTagName(tag);
// Test what kind of element we're dealing with here
if (tag.EqualsWithConversion("input", PR_TRUE))
{
// INPUT element - button, combo, checkbox, text etc.
flags |= nsIContextMenuListener::CONTEXT_INPUT;
}
else if (tag.EqualsWithConversion("img", PR_TRUE))
{
// IMG element
flags |= nsIContextMenuListener::CONTEXT_IMAGE;
}
else
{
// Something else
flags |= nsIContextMenuListener::CONTEXT_OTHER;
}
// Test if the element has an associated link
nsCOMPtr<nsIDOMNamedNodeMap> attributes;
node->GetAttributes(getter_AddRefs(attributes));
if (attributes)
{
nsCOMPtr<nsIDOMNode> hrefNode;
nsAutoString href; href.AssignWithConversion("href");
attributes->GetNamedItem(href, getter_AddRefs(hrefNode));
if (hrefNode)
{
flags |= nsIContextMenuListener::CONTEXT_LINK;
break;
}
}
}
nsCOMPtr<nsIDOMNode> parentNode;
node->GetParentNode(getter_AddRefs(parentNode));
// Test if we're at the top of the document
if (!parentNode)
{
node = nsnull;
flags |= nsIContextMenuListener::CONTEXT_DOCUMENT;
break;
}
node = parentNode;
} while (node);
// Tell the listener all about the event
menuListener->OnShowContextMenu(flags, aMouseEvent, node);
return NS_OK;
}
nsresult nsDocShellTreeOwner::MouseUp(nsIDOMEvent* aMouseEvent)
{
return NS_OK;
}
nsresult nsDocShellTreeOwner::MouseClick(nsIDOMEvent* aMouseEvent)
{
return NS_OK;
}
nsresult nsDocShellTreeOwner::MouseDblClick(nsIDOMEvent* aMouseEvent)
{
return NS_OK;
}
nsresult nsDocShellTreeOwner::MouseOver(nsIDOMEvent* aMouseEvent)
{
return NS_OK;
}
nsresult nsDocShellTreeOwner::MouseOut(nsIDOMEvent* aMouseEvent)
{
return NS_OK;
}

View File

@ -33,32 +33,69 @@
#include "nsIInterfaceRequestor.h"
#include "nsIWebBrowserChrome.h"
#include "nsIWebProgressListener.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMDocument.h"
#include "nsCommandHandler.h"
class nsWebBrowser;
// {6D10C180-6888-11d4-952B-0020183BF181}
#define NS_ICDOCSHELLTREEOWNER_IID \
{ 0x6d10c180, 0x6888, 0x11d4, { 0x95, 0x2b, 0x0, 0x20, 0x18, 0x3b, 0xf1, 0x81 } }
/*
* This is a fake 'hidden' interface that nsDocShellTreeOwner implements.
* Classes such as nsCommandHandler can QI for this interface to be
* sure that they're dealing with a valid nsDocShellTreeOwner and not some
* other object that implements nsIDocShellTreeOwner.
*/
class nsICDocShellTreeOwner : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICDOCSHELLTREEOWNER_IID)
};
class nsDocShellTreeOwner : public nsIDocShellTreeOwner,
public nsIBaseWindow,
public nsIInterfaceRequestor,
public nsIWebProgressListener
public nsIWebProgressListener,
public nsIDOMMouseListener,
public nsICDocShellTreeOwner
{
friend class nsWebBrowser;
friend class nsCommandHandler;
public:
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
NS_DECL_NSIBASEWINDOW
NS_DECL_NSIDOCSHELLTREEOWNER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBPROGRESSLISTENER
NS_DECL_NSIBASEWINDOW
NS_DECL_NSIDOCSHELLTREEOWNER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBPROGRESSLISTENER
// nsIDOMMouseListener
virtual nsresult HandleEvent(nsIDOMEvent* aEvent);
virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent);
protected:
nsDocShellTreeOwner();
virtual ~nsDocShellTreeOwner();
nsDocShellTreeOwner();
virtual ~nsDocShellTreeOwner();
void WebBrowser(nsWebBrowser* aWebBrowser);
nsWebBrowser* WebBrowser();
NS_IMETHOD SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner);
NS_IMETHOD SetWebBrowserChrome(nsIWebBrowserChrome* aWebBrowserChrome);
void WebBrowser(nsWebBrowser* aWebBrowser);
nsWebBrowser* WebBrowser();
NS_IMETHOD SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner);
NS_IMETHOD SetWebBrowserChrome(nsIWebBrowserChrome* aWebBrowserChrome);
nsCOMPtr<nsIDOMDocument> mLastDOMDocument;
NS_IMETHOD AddMouseListener();
NS_IMETHOD RemoveMouseListener();
protected: