mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 376802 Use one global tooltip listener instead of creating one for each XUL element that needs one r=Smaug sr=jst
This commit is contained in:
parent
61877955f2
commit
af293ef660
@ -831,7 +831,6 @@ GK_ATOM(toolbarbutton, "toolbarbutton")
|
||||
GK_ATOM(toolbaritem, "toolbaritem")
|
||||
GK_ATOM(toolbox, "toolbox")
|
||||
GK_ATOM(tooltip, "tooltip")
|
||||
GK_ATOM(tooltiplistener, "tooltiplistener")
|
||||
GK_ATOM(tooltiptext, "tooltiptext")
|
||||
GK_ATOM(top, "top")
|
||||
GK_ATOM(topmargin, "topmargin")
|
||||
|
@ -83,6 +83,7 @@
|
||||
#include "nsXULContentUtils.h"
|
||||
#include "nsXULElement.h"
|
||||
#include "nsXULPrototypeCache.h"
|
||||
#include "nsXULTooltipListener.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
@ -241,6 +242,7 @@ nsLayoutStatics::Shutdown()
|
||||
nsXULElement::ReleaseGlobals();
|
||||
nsXULPrototypeCache::ReleaseGlobals();
|
||||
nsXULPrototypeElement::ReleaseGlobals();
|
||||
nsXULTooltipListener::ReleaseInstance();
|
||||
nsSprocketLayout::Shutdown();
|
||||
#endif
|
||||
|
||||
|
@ -311,42 +311,16 @@ nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
|
||||
mDefaultTooltip = aTooltip;
|
||||
}
|
||||
|
||||
static void
|
||||
TooltipListenerPropertyDtor(void *aObject, nsIAtom *aPropertyName,
|
||||
void *aPropertyValue, void *aData)
|
||||
{
|
||||
nsXULTooltipListener* listener =
|
||||
NS_STATIC_CAST(nsXULTooltipListener*, aPropertyValue);
|
||||
if (listener) {
|
||||
listener->RemoveTooltipSupport(NS_STATIC_CAST(nsIContent*, aObject));
|
||||
NS_RELEASE(listener);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||
nsRefPtr<nsXULTooltipListener> listener =
|
||||
NS_STATIC_CAST(nsXULTooltipListener*,
|
||||
aNode->GetProperty(nsGkAtoms::tooltiplistener));
|
||||
if (listener) {
|
||||
// Tooltip listener is already installed.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
listener = new nsXULTooltipListener();
|
||||
nsXULTooltipListener *listener = nsXULTooltipListener::GetInstance();
|
||||
if (!listener)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_SUCCEEDED(listener->Init(aNode))) {
|
||||
nsresult rv = aNode->SetProperty(nsGkAtoms::tooltiplistener, listener,
|
||||
TooltipListenerPropertyDtor, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsXULTooltipListener* listenerRef = listener;
|
||||
NS_ADDREF(listenerRef);
|
||||
}
|
||||
return NS_OK;
|
||||
return listener->AddTooltipSupport(aNode);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -61,6 +61,8 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIRootBox.h"
|
||||
|
||||
nsXULTooltipListener* nsXULTooltipListener::mInstance = nsnull;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//// nsISupports
|
||||
|
||||
@ -199,7 +201,11 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
|
||||
mMouseClientX = newMouseX;
|
||||
mMouseClientY = newMouseY;
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
aMouseEvent->GetCurrentTarget(getter_AddRefs(eventTarget));
|
||||
mSourceNode = do_QueryInterface(eventTarget);
|
||||
#ifdef MOZ_XUL
|
||||
mIsSourceTree = mSourceNode->Tag() == nsGkAtoms::treechildren;
|
||||
if (mIsSourceTree)
|
||||
CheckTreeBodyMove(mouseEvent);
|
||||
#endif
|
||||
@ -215,17 +221,15 @@ nsXULTooltipListener::MouseMove(nsIDOMEvent* aMouseEvent)
|
||||
if (!mCurrentTooltip) {
|
||||
mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if (mTooltipTimer) {
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
|
||||
if (eventTarget) {
|
||||
nsCOMPtr<nsIContent> targetContent(do_QueryInterface(eventTarget));
|
||||
mTargetNode = targetContent;
|
||||
}
|
||||
mTargetNode = do_QueryInterface(eventTarget);
|
||||
if (mTargetNode) {
|
||||
nsresult rv = mTooltipTimer->InitWithFuncCallback(sTooltipCallback, this,
|
||||
kTooltipShowTime, nsITimer::TYPE_ONE_SHOT);
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
mTargetNode = nsnull;
|
||||
mSourceNode = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -284,22 +288,6 @@ nsXULTooltipListener::PopupHiding(nsIDOMEvent* aEvent)
|
||||
PRBool nsXULTooltipListener::sShowTooltips = PR_FALSE;
|
||||
PRUint32 nsXULTooltipListener::sTooltipListenerCount = 0;
|
||||
|
||||
// XXX: This could all be done in the ctor.
|
||||
nsresult
|
||||
nsXULTooltipListener::Init(nsIContent* aSourceNode)
|
||||
{
|
||||
mSourceNode = aSourceNode;
|
||||
AddTooltipSupport(aSourceNode);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
// if the target is an treechildren, we may have some special
|
||||
// case handling to do
|
||||
mIsSourceTree = mSourceNode->Tag() == nsGkAtoms::treechildren;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULTooltipListener::AddTooltipSupport(nsIContent* aNode)
|
||||
{
|
||||
@ -307,8 +295,8 @@ nsXULTooltipListener::AddTooltipSupport(nsIContent* aNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aNode));
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_TRUE);
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_TRUE);
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -320,8 +308,8 @@ nsXULTooltipListener::RemoveTooltipSupport(nsIContent* aNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> evtTarget(do_QueryInterface(aNode));
|
||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_TRUE);
|
||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_TRUE);
|
||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||
evtTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), (nsIDOMMouseListener*)this, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -369,9 +357,7 @@ nsXULTooltipListener::CheckTreeBodyMove(nsIDOMMouseEvent* aMouseEvent)
|
||||
// XXX check the disabletitletips attribute on the tree content
|
||||
mNeedTitletip = PR_FALSE;
|
||||
if (row >= 0 && obj.EqualsLiteral("text")) {
|
||||
PRBool isCropped;
|
||||
obx->IsCellCropped(row, col, &isCropped);
|
||||
mNeedTitletip = isCropped;
|
||||
obx->IsCellCropped(row, col, &mNeedTitletip);
|
||||
}
|
||||
|
||||
if (mCurrentTooltip && (row != mLastTreeRow || col != mLastTreeCol)) {
|
||||
@ -405,8 +391,7 @@ nsXULTooltipListener::ShowTooltip()
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(mTargetNode));
|
||||
xulDoc->SetTooltipNode(targetNode);
|
||||
xulDoc->SetTooltipNode(mTargetNode);
|
||||
LaunchTooltip(mSourceNode, mMouseClientX, mMouseClientY);
|
||||
mTargetNode = nsnull;
|
||||
|
||||
@ -440,6 +425,7 @@ nsXULTooltipListener::ShowTooltip()
|
||||
evtTarget->AddEventListener(NS_LITERAL_STRING("keydown"),
|
||||
(nsIDOMMouseListener*)this, PR_TRUE);
|
||||
}
|
||||
mSourceNode = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
@ -699,6 +685,10 @@ nsXULTooltipListener::DestroyTooltip()
|
||||
|
||||
// kill any ongoing timers
|
||||
KillTooltipTimer();
|
||||
mSourceNode = nsnull;
|
||||
#ifdef MOZ_XUL
|
||||
mLastTreeCol = nsnull;
|
||||
#endif
|
||||
if (mAutoHideTimer) {
|
||||
mAutoHideTimer->Cancel();
|
||||
mAutoHideTimer = nsnull;
|
||||
@ -734,19 +724,15 @@ nsXULTooltipListener::CreateAutoHideTimer()
|
||||
void
|
||||
nsXULTooltipListener::sTooltipCallback(nsITimer *aTimer, void *aListener)
|
||||
{
|
||||
nsXULTooltipListener* self = NS_STATIC_CAST(nsXULTooltipListener*, aListener);
|
||||
if (self)
|
||||
self->ShowTooltip();
|
||||
if (mInstance)
|
||||
mInstance->ShowTooltip();
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTooltipListener::sAutoHideCallback(nsITimer *aTimer, void* aListener)
|
||||
{
|
||||
nsXULTooltipListener* self = NS_STATIC_CAST(nsXULTooltipListener*, aListener);
|
||||
if (self) {
|
||||
nsCOMPtr<nsIDOMMouseListener> kungFuDeathGrip(self);
|
||||
self->HideTooltip();
|
||||
}
|
||||
if (mInstance)
|
||||
mInstance->HideTooltip();
|
||||
}
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -60,9 +60,6 @@ class nsXULTooltipListener : public nsIDOMMouseListener,
|
||||
{
|
||||
public:
|
||||
|
||||
nsXULTooltipListener();
|
||||
virtual ~nsXULTooltipListener();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
@ -96,12 +93,20 @@ public:
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
nsresult Init(nsIContent* aSourceNode);
|
||||
nsresult AddTooltipSupport(nsIContent* aNode);
|
||||
nsresult RemoveTooltipSupport(nsIContent* aNode);
|
||||
static nsXULTooltipListener* GetInstance() {
|
||||
if (!mInstance)
|
||||
NS_IF_ADDREF(mInstance = new nsXULTooltipListener());
|
||||
return mInstance;
|
||||
}
|
||||
static void ReleaseInstance() { NS_IF_RELEASE(mInstance); }
|
||||
|
||||
protected:
|
||||
|
||||
nsXULTooltipListener();
|
||||
~nsXULTooltipListener();
|
||||
|
||||
// pref callback for when the "show tooltips" pref changes
|
||||
static int sTooltipPrefChanged (const char* aPref, void* aData);
|
||||
static PRBool sShowTooltips;
|
||||
@ -125,10 +130,11 @@ protected:
|
||||
// can be really used (i.e. tooltip is not a menu).
|
||||
nsresult GetTooltipFor(nsIContent* aTarget, nsIContent** aTooltip);
|
||||
|
||||
static nsXULTooltipListener* mInstance;
|
||||
static int ToolbarTipsPrefChanged(const char *aPref, void *aClosure);
|
||||
|
||||
nsIContent* mSourceNode;
|
||||
nsCOMPtr<nsIContent> mTargetNode;
|
||||
nsCOMPtr<nsIContent> mSourceNode;
|
||||
nsCOMPtr<nsIDOMNode> mTargetNode;
|
||||
nsCOMPtr<nsIContent> mCurrentTooltip;
|
||||
|
||||
// a timer for showing the tooltip
|
||||
|
Loading…
Reference in New Issue
Block a user