зеркало из https://github.com/mozilla/pjs.git
93839 - tooltiptext should work without specifying tooltip, r=pinkerton, sr=hyatt
This commit is contained in:
Родитель
a5c0fa9511
Коммит
58fe14b67f
|
@ -646,7 +646,9 @@ NS_METHOD nsDOMEvent::GetScreenY(PRInt32* aScreenY)
|
|||
NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX)
|
||||
{
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT && mEvent->eventStructType != NS_DRAGDROP_EVENT) ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT
|
||||
&& mEvent->eventStructType != NS_EVENT
|
||||
&& mEvent->eventStructType != NS_DRAGDROP_EVENT) ||
|
||||
!mPresContext) {
|
||||
*aClientX = 0;
|
||||
return NS_OK;
|
||||
|
@ -697,7 +699,9 @@ NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX)
|
|||
NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY)
|
||||
{
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT && mEvent->eventStructType != NS_DRAGDROP_EVENT) ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT
|
||||
&& mEvent->eventStructType != NS_EVENT
|
||||
&& mEvent->eventStructType != NS_DRAGDROP_EVENT) ||
|
||||
!mPresContext) {
|
||||
*aClientY = 0;
|
||||
return NS_OK;
|
||||
|
|
|
@ -237,6 +237,8 @@ XUL_ATOM(textbox, "textbox")
|
|||
XUL_ATOM(textarea, "textarea")
|
||||
XUL_ATOM(listbox, "listbox")
|
||||
XUL_ATOM(tooltip, "tooltip")
|
||||
XUL_ATOM(titletip, "titletip")
|
||||
XUL_ATOM(tooltiptext, "tooltiptext")
|
||||
XUL_ATOM(context, "context")
|
||||
XUL_ATOM(contextmenu, "contextmenu")
|
||||
XUL_ATOM(style, "style")
|
||||
|
@ -302,3 +304,4 @@ XUL_ATOM(sortDirection, "sortDirection")
|
|||
XUL_ATOM(sortActive, "sortActive")
|
||||
XUL_ATOM(selectedIndex, "selectedIndex")
|
||||
XUL_ATOM(_star, "*")
|
||||
XUL_ATOM(defaultz, "default")
|
|
@ -2060,8 +2060,7 @@ nsXULElement::AddListenerFor(nsINodeInfo *aNodeInfo,
|
|||
nsCOMPtr<nsIAtom> attr;
|
||||
aNodeInfo->GetNameAtom(*getter_AddRefs(attr));
|
||||
|
||||
if (attr == nsXULAtoms::tooltip ||
|
||||
attr == nsXULAtoms::menu ||
|
||||
if (attr == nsXULAtoms::menu ||
|
||||
attr == nsXULAtoms::contextmenu ||
|
||||
// XXXdwh popup and context are deprecated
|
||||
attr == nsXULAtoms::popup ||
|
||||
|
@ -4576,10 +4575,7 @@ nsXULElement::AddPopupListener(nsIAtom* aName)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
XULPopupType popupType;
|
||||
if (aName == nsXULAtoms::tooltip) {
|
||||
popupType = eXULPopupType_tooltip;
|
||||
}
|
||||
else if (aName == nsXULAtoms::context || aName == nsXULAtoms::contextmenu) {
|
||||
if (aName == nsXULAtoms::context || aName == nsXULAtoms::contextmenu) {
|
||||
popupType = eXULPopupType_context;
|
||||
}
|
||||
else {
|
||||
|
@ -4592,15 +4588,8 @@ nsXULElement::AddPopupListener(nsIAtom* aName)
|
|||
// Add the popup as a listener on this element.
|
||||
nsCOMPtr<nsIDOMEventListener> eventListener = do_QueryInterface(popupListener);
|
||||
|
||||
if (popupType == eXULPopupType_tooltip) {
|
||||
AddEventListener(NS_LITERAL_STRING("mouseout"), eventListener, PR_FALSE);
|
||||
AddEventListener(NS_LITERAL_STRING("mousemove"), eventListener, PR_FALSE);
|
||||
AddEventListener(NS_LITERAL_STRING("keydown"), eventListener, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
AddEventListener(NS_LITERAL_STRING("mousedown"), eventListener, PR_FALSE);
|
||||
AddEventListener(NS_LITERAL_STRING("contextmenu"), eventListener, PR_FALSE);
|
||||
}
|
||||
AddEventListener(NS_LITERAL_STRING("mousedown"), eventListener, PR_FALSE);
|
||||
AddEventListener(NS_LITERAL_STRING("contextmenu"), eventListener, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -42,11 +42,10 @@
|
|||
|
||||
/*
|
||||
This file provides the implementation for xul popup listener which
|
||||
tracks xul popups, context menus, and tooltips
|
||||
tracks xul popups and context menus
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
|
@ -54,9 +53,7 @@
|
|||
#include "nsIDOMDocumentXBL.h"
|
||||
#include "nsIXULPopupListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMMouseMotionListener.h"
|
||||
#include "nsIDOMContextMenuListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsContentCID.h"
|
||||
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
|
@ -66,13 +63,11 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
|
||||
#include "nsIBoxObject.h"
|
||||
#include "nsIPopupBoxObject.h"
|
||||
#include "nsIMenuBoxObject.h"
|
||||
|
||||
// for event firing in context menus
|
||||
#include "nsIPresContext.h"
|
||||
|
@ -81,8 +76,6 @@
|
|||
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIStyleContext.h"
|
||||
#include "nsIPref.h"
|
||||
|
||||
|
||||
// on win32 and os/2, context menus come up on mouse up. On other platforms,
|
||||
// they appear on mouse down. Certain bits of code care about this difference.
|
||||
|
@ -100,13 +93,10 @@ static NS_DEFINE_IID(kXULPopupListenerCID, NS_XULPOPUPLISTENER_CID);
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
// PopupListenerImpl
|
||||
//
|
||||
// This is the popup listener implementation for popup menus, context menus,
|
||||
// and tooltips.
|
||||
// This is the popup listener implementation for popup menus and context menus.
|
||||
//
|
||||
class XULPopupListenerImpl : public nsIXULPopupListener,
|
||||
public nsIDOMMouseListener,
|
||||
public nsIDOMKeyListener,
|
||||
public nsIDOMMouseMotionListener,
|
||||
public nsIDOMContextMenuListener
|
||||
{
|
||||
public:
|
||||
|
@ -122,47 +112,26 @@ public:
|
|||
|
||||
// nsIDOMMouseListener
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; };
|
||||
NS_IMETHOD MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; };
|
||||
NS_IMETHOD MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; };
|
||||
NS_IMETHOD MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; };
|
||||
NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent) ;
|
||||
|
||||
// nsIDOMMouseMotionListener
|
||||
NS_IMETHOD MouseMove(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD DragMove(nsIDOMEvent* aMouseEvent) { return NS_OK; };
|
||||
NS_IMETHOD MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; };
|
||||
|
||||
// nsIDOMContextMenuListener
|
||||
NS_IMETHOD ContextMenu(nsIDOMEvent* aContextMenuEvent);
|
||||
|
||||
// nsIDOMKeyListener
|
||||
NS_IMETHOD KeyDown(nsIDOMEvent* aKeyEvent) ;
|
||||
NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent) ;
|
||||
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent) ;
|
||||
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
|
||||
|
||||
protected:
|
||||
|
||||
virtual void KillTooltipTimer ( ) ;
|
||||
|
||||
virtual nsresult LaunchPopup(nsIDOMEvent* anEvent);
|
||||
virtual nsresult LaunchPopup(PRInt32 aClientX, PRInt32 aClientY) ;
|
||||
virtual void ClosePopup ( ) ;
|
||||
|
||||
void CreateAutoHideTimer ( ) ;
|
||||
|
||||
nsresult FindDocumentForNode(nsIDOMNode* inNode, nsIDOMXULDocument** outDoc) ;
|
||||
virtual void ClosePopup();
|
||||
|
||||
private:
|
||||
|
||||
// various delays for tooltips
|
||||
enum {
|
||||
kTooltipAutoHideTime = 5000, // 5000ms = 5 seconds
|
||||
kTooltipShowTime = 500 // 500ms = 0.5 seconds
|
||||
};
|
||||
|
||||
nsresult PreLaunchPopup(nsIDOMEvent* aMouseEvent);
|
||||
nsresult FireFocusOnTargetContent(nsIDOMNode* aTargetNode);
|
||||
|
||||
|
@ -175,40 +144,12 @@ private:
|
|||
// The type of the popup
|
||||
XULPopupType popupType;
|
||||
|
||||
// a timer for determining if a tooltip should be displayed.
|
||||
nsCOMPtr<nsITimer> mTooltipTimer;
|
||||
static void sTooltipCallback ( nsITimer* aTimer, void* aListener ) ;
|
||||
PRInt32 mMouseClientX, mMouseClientY; // mouse coordinates for tooltip event
|
||||
|
||||
// a timer for auto-hiding the tooltip after a certain delay
|
||||
nsCOMPtr<nsITimer> mAutoHideTimer;
|
||||
static void sAutoHideCallback ( nsITimer* aTimer, void* aListener ) ;
|
||||
|
||||
// pref callback for when the "show tooltips" pref changes
|
||||
static int sTooltipPrefChanged ( const char*, void* );
|
||||
|
||||
// The following members are not used unless |popupType| is tooltip.
|
||||
static PRBool sShowTooltips; // mirrors the "show tooltips" pref
|
||||
|
||||
// The node hovered over that fired the timer. This may turn into the node that
|
||||
// triggered the tooltip, but only if the timer ever gets around to firing.
|
||||
// This is a strong reference, because the tooltip content can be destroyed while we're
|
||||
// waiting for the tooltip to pup up, and we need to detect that.
|
||||
// It's set only when the tooltip timer is created and launched. The timer must
|
||||
// either fire or be cancelled (or possibly released?), and we release this
|
||||
// reference in each of those cases. So we don't leak.
|
||||
nsCOMPtr<nsIDOMNode> mPossibleTooltipNode;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRBool XULPopupListenerImpl::sShowTooltips = PR_FALSE;
|
||||
|
||||
|
||||
XULPopupListenerImpl::XULPopupListenerImpl(void)
|
||||
: mElement(nsnull), mPopupContent(nsnull),
|
||||
mMouseClientX(0), mMouseClientY(0)
|
||||
: mElement(nsnull), mPopupContent(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
@ -230,9 +171,7 @@ NS_IMPL_RELEASE(XULPopupListenerImpl)
|
|||
NS_INTERFACE_MAP_BEGIN(XULPopupListenerImpl)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXULPopupListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMContextMenuListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXULPopupListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
@ -242,54 +181,12 @@ XULPopupListenerImpl::Init(nsIDOMElement* aElement, const XULPopupType& popup)
|
|||
{
|
||||
mElement = aElement; // Weak reference. Don't addref it.
|
||||
popupType = popup;
|
||||
static PRBool prefChangeRegistered = PR_FALSE;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Only the first time, register the callback and get the initial value of the pref
|
||||
if ( !prefChangeRegistered ) {
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if ( prefs ) {
|
||||
// get the initial value of the pref
|
||||
rv = prefs->GetBoolPref("browser.chrome.toolbar_tips", &sShowTooltips);
|
||||
if ( NS_SUCCEEDED(rv) ) {
|
||||
// register the callback so we get notified of updates
|
||||
rv = prefs->RegisterCallback("browser.chrome.toolbar_tips", (PrefChangedFunc)sTooltipPrefChanged, nsnull);
|
||||
if ( NS_SUCCEEDED(rv) ){
|
||||
prefChangeRegistered = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// sTooltipPrefChanged
|
||||
//
|
||||
// Called when the tooltip pref changes. Refetch it.
|
||||
int
|
||||
XULPopupListenerImpl :: sTooltipPrefChanged (const char *, void * inData )
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv));
|
||||
if ( prefs ) {
|
||||
rv = prefs->GetBoolPref("browser.chrome.toolbar_tips", &sShowTooltips);
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
} // sTooltipPrefChanged
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// nsIDOMMouseListener
|
||||
|
||||
nsresult
|
||||
XULPopupListenerImpl::MouseUp(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
XULPopupListenerImpl::MouseDown(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
|
@ -370,9 +267,7 @@ XULPopupListenerImpl::PreLaunchPopup(nsIDOMEvent* aMouseEvent)
|
|||
}
|
||||
|
||||
// Store clicked-on node in xul document for context menus and menu popups.
|
||||
// Tooltips are stored in tooltipNode instead.
|
||||
if (popupType != eXULPopupType_tooltip)
|
||||
xulDocument->SetPopupNode( targetNode );
|
||||
xulDocument->SetPopupNode( targetNode );
|
||||
|
||||
switch (popupType) {
|
||||
case eXULPopupType_popup:
|
||||
|
@ -397,16 +292,6 @@ XULPopupListenerImpl::PreLaunchPopup(nsIDOMEvent* aMouseEvent)
|
|||
aMouseEvent->PreventBubble();
|
||||
aMouseEvent->PreventDefault();
|
||||
break;
|
||||
|
||||
case eXULPopupType_tooltip:
|
||||
// get rid of the tooltip on a mousedown.
|
||||
ClosePopup();
|
||||
break;
|
||||
|
||||
case eXULPopupType_blur:
|
||||
// what on earth is this?!
|
||||
break;
|
||||
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -468,180 +353,16 @@ XULPopupListenerImpl::FireFocusOnTargetContent(nsIDOMNode* aTargetNode)
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MouseMove
|
||||
//
|
||||
// If we're a tooltip, fire off a timer to see if a tooltip should be shown.
|
||||
//
|
||||
nsresult
|
||||
XULPopupListenerImpl::MouseMove(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
// make sure we're a tooltip. if not, bail.
|
||||
if ( popupType != eXULPopupType_tooltip )
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMMouseEvent> mouseEvent ( do_QueryInterface(aMouseEvent) );
|
||||
if (!mouseEvent)
|
||||
return NS_OK;
|
||||
|
||||
// don't kick off the timer or do any hard work if the pref is turned off
|
||||
if ( !sShowTooltips )
|
||||
return NS_OK;
|
||||
|
||||
// stash the coordinates of the event so that we can still get back to it from within the
|
||||
// timer callback. On win32, we'll get a MouseMove event even when a popup goes away --
|
||||
// even when the mouse doesn't change position! To get around this, we make sure the
|
||||
// mouse has really moved before proceeding.
|
||||
PRInt32 newMouseX, newMouseY;
|
||||
mouseEvent->GetClientX(&newMouseX);
|
||||
mouseEvent->GetClientY(&newMouseY);
|
||||
if ( mMouseClientX == newMouseX && mMouseClientY == newMouseY )
|
||||
return NS_OK;
|
||||
mMouseClientX = newMouseX; mMouseClientY = newMouseY;
|
||||
|
||||
// as the mouse moves, we want to make sure we reset the timer to show it,
|
||||
// so that the delay is from when the mouse stops moving, not when it enters
|
||||
// the node.
|
||||
KillTooltipTimer();
|
||||
|
||||
// If the mouse moves while the popup is up, don't do anything. We make it
|
||||
// go away only if it times out or leaves the tooltip node. If nothing is
|
||||
// showing, though, we have to do the work. We can tell if we have a popup
|
||||
// showing because |mPopupContent| will be non-null.
|
||||
if ( !mPopupContent ) {
|
||||
mTooltipTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if ( mTooltipTimer ) {
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
|
||||
if ( eventTarget )
|
||||
mPossibleTooltipNode = do_QueryInterface(eventTarget);
|
||||
if ( mPossibleTooltipNode ) {
|
||||
nsresult rv = mTooltipTimer->Init(sTooltipCallback, this, kTooltipShowTime, NS_PRIORITY_HIGH);
|
||||
if (NS_FAILED(rv))
|
||||
mPossibleTooltipNode = nsnull;
|
||||
}
|
||||
}
|
||||
else
|
||||
NS_WARNING ( "Could not create a timer for tooltip tracking" );
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
} // MouseMove
|
||||
|
||||
|
||||
//
|
||||
// MouseOut
|
||||
//
|
||||
// If we're a tooltip, hide any tip that might be showing and remove any
|
||||
// timer that is pending since the mouse is no longer over this area.
|
||||
//
|
||||
nsresult
|
||||
XULPopupListenerImpl::MouseOut(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
// make sure we're a tooltip. if not, bail.
|
||||
if ( popupType != eXULPopupType_tooltip )
|
||||
return NS_OK;
|
||||
|
||||
// mouse is leaving something which means it is in motion. Kill
|
||||
// our timer, but don't close anything just yet. We need to wait
|
||||
// and see if we're leaving the right node.
|
||||
KillTooltipTimer();
|
||||
|
||||
// which node did the mouse leave?
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
|
||||
nsCOMPtr<nsIDOMNode> eventNode ( do_QueryInterface(eventTarget) );
|
||||
|
||||
// which node is our tooltip on?
|
||||
nsCOMPtr<nsIDOMXULDocument> doc;
|
||||
FindDocumentForNode ( mElement, getter_AddRefs(doc) );
|
||||
nsCOMPtr<nsIDOMNode> tooltipNode;
|
||||
doc->GetTooltipNode ( getter_AddRefs(tooltipNode) );
|
||||
|
||||
// if they're the same, the mouse left the node the tooltip appeared on,
|
||||
// close the popup.
|
||||
if ( tooltipNode == eventNode )
|
||||
ClosePopup();
|
||||
return NS_OK;
|
||||
|
||||
} // MouseOut
|
||||
|
||||
|
||||
//
|
||||
// KeyDown
|
||||
//
|
||||
// If we're a tooltip, hide any tip that might be showing and remove any
|
||||
// timer that is pending since the mouse is no longer over this area.
|
||||
//
|
||||
nsresult
|
||||
XULPopupListenerImpl::KeyDown(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
// make sure we're a tooltip. if not, bail.
|
||||
if ( popupType != eXULPopupType_tooltip )
|
||||
return NS_OK;
|
||||
|
||||
ClosePopup();
|
||||
return NS_OK;
|
||||
|
||||
} // KeyDown
|
||||
|
||||
|
||||
//
|
||||
// KeyUp
|
||||
// KeyPress
|
||||
//
|
||||
// We can ignore these as they are already handled by KeyDown
|
||||
//
|
||||
nsresult
|
||||
XULPopupListenerImpl::KeyUp(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
|
||||
} // KeyUp
|
||||
|
||||
nsresult
|
||||
XULPopupListenerImpl::KeyPress(nsIDOMEvent* aMouseEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
|
||||
} // KeyPress
|
||||
|
||||
|
||||
//
|
||||
// KillTooltipTimer
|
||||
//
|
||||
// Stop the timer that would show a tooltip dead in its tracks
|
||||
//
|
||||
void
|
||||
XULPopupListenerImpl :: KillTooltipTimer ( )
|
||||
{
|
||||
if ( mTooltipTimer ) {
|
||||
mTooltipTimer->Cancel();
|
||||
mTooltipTimer = nsnull;
|
||||
mPossibleTooltipNode = nsnull; // release tooltip target
|
||||
}
|
||||
} // KillTooltipTimer
|
||||
|
||||
|
||||
//
|
||||
// ClosePopup
|
||||
//
|
||||
// Do everything needed to shut down the popup, including killing off all
|
||||
// the timers that may be involved.
|
||||
// Do everything needed to shut down the popup.
|
||||
//
|
||||
// NOTE: This routine is safe to call even if the popup is already closed.
|
||||
//
|
||||
void
|
||||
XULPopupListenerImpl :: ClosePopup ( )
|
||||
{
|
||||
KillTooltipTimer();
|
||||
if ( mAutoHideTimer ) {
|
||||
mAutoHideTimer->Cancel();
|
||||
mAutoHideTimer = nsnull;
|
||||
}
|
||||
|
||||
if ( mPopupContent ) {
|
||||
nsCOMPtr<nsIDOMXULElement> popupElement(do_QueryInterface(mPopupContent));
|
||||
nsCOMPtr<nsIBoxObject> boxObject;
|
||||
|
@ -652,52 +373,10 @@ XULPopupListenerImpl :: ClosePopup ( )
|
|||
popupObject->HidePopup();
|
||||
|
||||
mPopupContent = nsnull; // release the popup
|
||||
|
||||
// clear out the tooltip node on the document
|
||||
nsCOMPtr<nsIDOMXULDocument> doc;
|
||||
FindDocumentForNode ( mElement, getter_AddRefs(doc) );
|
||||
if ( doc )
|
||||
doc->SetTooltipNode(nsnull);
|
||||
}
|
||||
|
||||
} // ClosePopup
|
||||
|
||||
|
||||
//
|
||||
// FindDocumentForNode
|
||||
//
|
||||
// Given a DOM content node, finds the XUL document associated with it
|
||||
//
|
||||
nsresult
|
||||
XULPopupListenerImpl :: FindDocumentForNode ( nsIDOMNode* inElement, nsIDOMXULDocument** outDoc )
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if ( !outDoc || !inElement )
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// get the document associated with this content element
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(inElement);
|
||||
if ( !content || NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document))) ) {
|
||||
NS_ERROR("Unable to retrieve the document.");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMXULDocument> xulDocument = do_QueryInterface(document);
|
||||
if ( !xulDocument ) {
|
||||
NS_ERROR("Popup attached to an element that isn't in XUL!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*outDoc = xulDocument;
|
||||
NS_ADDREF ( *outDoc );
|
||||
|
||||
return rv;
|
||||
|
||||
} // FindDocumentForNode
|
||||
|
||||
|
||||
//
|
||||
// LaunchPopup
|
||||
//
|
||||
|
@ -795,7 +474,7 @@ static void ConvertPosition(nsIDOMElement* aPopupElt, nsString& aAnchor, nsStrin
|
|||
// content.
|
||||
//
|
||||
// This looks for an attribute on |aElement| of the appropriate popup type
|
||||
// (popup, context, tooltip) and uses that attribute's value as an ID for
|
||||
// (popup, context) and uses that attribute's value as an ID for
|
||||
// the popup content in the document.
|
||||
//
|
||||
nsresult
|
||||
|
@ -813,8 +492,6 @@ XULPopupListenerImpl::LaunchPopup(PRInt32 aClientX, PRInt32 aClientY)
|
|||
aClientX += 2;
|
||||
aClientY += 2;
|
||||
}
|
||||
else if ( popupType == eXULPopupType_tooltip )
|
||||
type.AssignWithConversion("tooltip");
|
||||
|
||||
nsAutoString identifier;
|
||||
mElement->GetAttribute(type, identifier);
|
||||
|
@ -828,9 +505,7 @@ XULPopupListenerImpl::LaunchPopup(PRInt32 aClientX, PRInt32 aClientY)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Try to find the popup content and the document. We don't use FindDocumentForNode()
|
||||
// in this case because we need the nsIDocument interface anyway for the script
|
||||
// context.
|
||||
// Try to find the popup content and the document.
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
|
||||
if (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
|
||||
|
@ -851,7 +526,7 @@ XULPopupListenerImpl::LaunchPopup(PRInt32 aClientX, PRInt32 aClientY)
|
|||
if (identifier == NS_LITERAL_STRING("_child")) {
|
||||
nsCOMPtr<nsIContent> popup;
|
||||
|
||||
nsIAtom* tag = (popupType == eXULPopupType_tooltip) ? nsXULAtoms::tooltip : nsXULAtoms::menupopup;
|
||||
nsIAtom* tag = nsXULAtoms::menupopup;
|
||||
|
||||
GetImmediateChild(content, tag, getter_AddRefs(popup));
|
||||
if (popup)
|
||||
|
@ -925,95 +600,6 @@ XULPopupListenerImpl::LaunchPopup(PRInt32 aClientX, PRInt32 aClientY)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// sTooltipCallback
|
||||
//
|
||||
// A timer callback, fired when the mouse has hovered inside of a frame for the
|
||||
// appropriate amount of time. Getting to this point means that we should show the
|
||||
// toolip.
|
||||
//
|
||||
// This relies on certain things being cached into the |aPopupListener|
|
||||
// object passed to us by the timer:
|
||||
// -- the x/y coordinates of the mouse (mMouseClientY, mMouseClientX)
|
||||
// -- the dom node the user hovered over (mPossibleTooltipNode)
|
||||
//
|
||||
void
|
||||
XULPopupListenerImpl :: sTooltipCallback (nsITimer *aTimer, void *aPopupListener)
|
||||
{
|
||||
XULPopupListenerImpl* self = NS_STATIC_CAST(XULPopupListenerImpl*, aPopupListener);
|
||||
if ( self && self->mPossibleTooltipNode ) {
|
||||
// set the node in the document that triggered the tooltip and show it
|
||||
nsCOMPtr<nsIDOMXULDocument> doc;
|
||||
self->FindDocumentForNode ( self->mElement, getter_AddRefs(doc) );
|
||||
if ( doc ) {
|
||||
// Make sure the target node is still attached to some document. It might have been deleted.
|
||||
nsCOMPtr<nsIDOMDocument> targetDoc;
|
||||
self->mPossibleTooltipNode->GetOwnerDocument(getter_AddRefs(targetDoc));
|
||||
if ( targetDoc ) {
|
||||
doc->SetTooltipNode ( self->mPossibleTooltipNode );
|
||||
doc->SetPopupNode ( self->mPossibleTooltipNode );
|
||||
self->LaunchPopup ( self->mMouseClientX, self->mMouseClientY+21);
|
||||
|
||||
// at this point, |mPopupContent| holds the content node of
|
||||
// the popup. If there is an attribute on the popup telling us
|
||||
// not to create the auto-hide timer, don't.
|
||||
if ( self->mPopupContent ) {
|
||||
nsAutoString noAutoHide;
|
||||
self->mPopupContent->GetAttribute ( NS_LITERAL_STRING("noautohide"), noAutoHide );
|
||||
if ( noAutoHide != NS_LITERAL_STRING("true") )
|
||||
self->CreateAutoHideTimer();
|
||||
}
|
||||
|
||||
} // if tooltip target's document exists
|
||||
} // if document
|
||||
|
||||
// release tooltip target if there is one, NO MATTER WHAT
|
||||
self->mPossibleTooltipNode = nsnull;
|
||||
} // if "self" data valid
|
||||
|
||||
} // sTooltipCallback
|
||||
|
||||
|
||||
//
|
||||
// CreateAutoHideTimer
|
||||
//
|
||||
// Create a new timer to see if we should auto-hide. It's ok if this fails.
|
||||
//
|
||||
void
|
||||
XULPopupListenerImpl :: CreateAutoHideTimer ( )
|
||||
{
|
||||
// just to be anal (er, safe)
|
||||
if ( mAutoHideTimer ) {
|
||||
mAutoHideTimer->Cancel();
|
||||
mAutoHideTimer = nsnull;
|
||||
}
|
||||
|
||||
mAutoHideTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
if ( mAutoHideTimer )
|
||||
mAutoHideTimer->Init(sAutoHideCallback, this, kTooltipAutoHideTime, NS_PRIORITY_HIGH);
|
||||
|
||||
} // CreateAutoHideTimer
|
||||
|
||||
|
||||
//
|
||||
// sAutoHideCallback
|
||||
//
|
||||
// This fires after a tooltip has been open for a certain length of time. Just tell
|
||||
// the listener to close the popup. We don't have to worry, because ClosePopup() can
|
||||
// be called multiple times, even if the popup has already been closed.
|
||||
//
|
||||
void
|
||||
XULPopupListenerImpl :: sAutoHideCallback ( nsITimer *aTimer, void* aListener )
|
||||
{
|
||||
XULPopupListenerImpl* self = NS_STATIC_CAST(XULPopupListenerImpl*, aListener);
|
||||
if ( self )
|
||||
self->ClosePopup();
|
||||
|
||||
// NOTE: |aTimer| and |self->mAutoHideTimer| are invalid after calling ClosePopup();
|
||||
|
||||
} // sAutoHideCallback
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
NS_NewXULPopupListener(nsIXULPopupListener** pop)
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
#include "nsRuleNode.h"
|
||||
#include "nsIXULDocument.h"
|
||||
#include "nsIPrintPreviewContext.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
|
||||
|
@ -5522,6 +5523,21 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
isReplaced = PR_TRUE;
|
||||
rv = NS_NewMenuPopupFrame(aPresShell, &newFrame);
|
||||
|
||||
if (aTag == nsXULAtoms::tooltip) {
|
||||
nsAutoString defaultTooltip;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::defaultz, defaultTooltip);
|
||||
if (defaultTooltip.EqualsIgnoreCase("true")) {
|
||||
// Locate the root frame and tell it about the tooltip.
|
||||
nsIFrame* rootFrame = nsnull;
|
||||
aState.mFrameManager->GetRootFrame(&rootFrame);
|
||||
if (rootFrame)
|
||||
rootFrame->FirstChild(aPresContext, nsnull, &rootFrame);
|
||||
nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
|
||||
if (rootBox)
|
||||
rootBox->SetDefaultTooltip(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
// If a popup is inside a menu, then the menu understands the complex
|
||||
// rules/behavior governing the cascade of multiple menu popups and can handle
|
||||
// having the real popup frame placed under it as a child.
|
||||
|
@ -5650,6 +5666,24 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
aFrameItems.AddChild(topFrame);
|
||||
}
|
||||
|
||||
|
||||
// register tooltip support if needed
|
||||
nsAutoString value;
|
||||
if (aTag == nsXULAtoms::outlinerbody || // outliners always need titletips
|
||||
aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::tooltiptext, value) !=
|
||||
NS_CONTENT_ATTR_NOT_THERE ||
|
||||
aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::tooltip, value) !=
|
||||
NS_CONTENT_ATTR_NOT_THERE)
|
||||
{
|
||||
nsIFrame* rootFrame = nsnull;
|
||||
aState.mFrameManager->GetRootFrame(&rootFrame);
|
||||
if (rootFrame)
|
||||
rootFrame->FirstChild(aPresContext, nsnull, &rootFrame);
|
||||
nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
|
||||
if (rootBox)
|
||||
rootBox->AddTooltipSupport(aContent);
|
||||
}
|
||||
|
||||
// addToHashTable:
|
||||
|
||||
if (topFrame) {
|
||||
|
@ -10106,6 +10140,23 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|||
tag.get() == nsXULAtoms::treerow || tag.get() == nsXULAtoms::treecell))
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aAttribute == nsXULAtoms::tooltiptext ||
|
||||
aAttribute == nsXULAtoms::tooltip)
|
||||
{
|
||||
nsIFrame* rootFrame = nsnull;
|
||||
shell->GetRootFrame(&rootFrame);
|
||||
if (rootFrame)
|
||||
rootFrame->FirstChild(aPresContext, nsnull, &rootFrame);
|
||||
nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
|
||||
if (rootBox) {
|
||||
if (aModType == nsIDOMMutationEvent::REMOVAL)
|
||||
rootBox->RemoveTooltipSupport(aContent);
|
||||
if (aModType == nsIDOMMutationEvent::ADDITION)
|
||||
rootBox->AddTooltipSupport(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INCLUDE_XUL
|
||||
|
||||
// check for inline style. we need to clear the data at the style context's rule
|
||||
|
|
|
@ -103,6 +103,7 @@
|
|||
#include "nsRuleNode.h"
|
||||
#include "nsIXULDocument.h"
|
||||
#include "nsIPrintPreviewContext.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
|
||||
|
@ -5522,6 +5523,21 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
isReplaced = PR_TRUE;
|
||||
rv = NS_NewMenuPopupFrame(aPresShell, &newFrame);
|
||||
|
||||
if (aTag == nsXULAtoms::tooltip) {
|
||||
nsAutoString defaultTooltip;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::defaultz, defaultTooltip);
|
||||
if (defaultTooltip.EqualsIgnoreCase("true")) {
|
||||
// Locate the root frame and tell it about the tooltip.
|
||||
nsIFrame* rootFrame = nsnull;
|
||||
aState.mFrameManager->GetRootFrame(&rootFrame);
|
||||
if (rootFrame)
|
||||
rootFrame->FirstChild(aPresContext, nsnull, &rootFrame);
|
||||
nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
|
||||
if (rootBox)
|
||||
rootBox->SetDefaultTooltip(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
// If a popup is inside a menu, then the menu understands the complex
|
||||
// rules/behavior governing the cascade of multiple menu popups and can handle
|
||||
// having the real popup frame placed under it as a child.
|
||||
|
@ -5650,6 +5666,24 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
|
|||
aFrameItems.AddChild(topFrame);
|
||||
}
|
||||
|
||||
|
||||
// register tooltip support if needed
|
||||
nsAutoString value;
|
||||
if (aTag == nsXULAtoms::outlinerbody || // outliners always need titletips
|
||||
aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::tooltiptext, value) !=
|
||||
NS_CONTENT_ATTR_NOT_THERE ||
|
||||
aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::tooltip, value) !=
|
||||
NS_CONTENT_ATTR_NOT_THERE)
|
||||
{
|
||||
nsIFrame* rootFrame = nsnull;
|
||||
aState.mFrameManager->GetRootFrame(&rootFrame);
|
||||
if (rootFrame)
|
||||
rootFrame->FirstChild(aPresContext, nsnull, &rootFrame);
|
||||
nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
|
||||
if (rootBox)
|
||||
rootBox->AddTooltipSupport(aContent);
|
||||
}
|
||||
|
||||
// addToHashTable:
|
||||
|
||||
if (topFrame) {
|
||||
|
@ -10106,6 +10140,23 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
|||
tag.get() == nsXULAtoms::treerow || tag.get() == nsXULAtoms::treecell))
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aAttribute == nsXULAtoms::tooltiptext ||
|
||||
aAttribute == nsXULAtoms::tooltip)
|
||||
{
|
||||
nsIFrame* rootFrame = nsnull;
|
||||
shell->GetRootFrame(&rootFrame);
|
||||
if (rootFrame)
|
||||
rootFrame->FirstChild(aPresContext, nsnull, &rootFrame);
|
||||
nsCOMPtr<nsIRootBox> rootBox(do_QueryInterface(rootFrame));
|
||||
if (rootBox) {
|
||||
if (aModType == nsIDOMMutationEvent::REMOVAL)
|
||||
rootBox->RemoveTooltipSupport(aContent);
|
||||
if (aModType == nsIDOMMutationEvent::ADDITION)
|
||||
rootBox->AddTooltipSupport(aContent);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INCLUDE_XUL
|
||||
|
||||
// check for inline style. we need to clear the data at the style context's rule
|
||||
|
|
Двоичные данные
layout/macbuild/layout.mcp
Двоичные данные
layout/macbuild/layout.mcp
Двоичный файл не отображается.
|
@ -105,6 +105,7 @@ CPPSRCS = \
|
|||
nsRepeatService.cpp \
|
||||
nsTitleBarFrame.cpp \
|
||||
nsResizerFrame.cpp \
|
||||
nsXULTooltipListener.cpp \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
|
|
@ -103,6 +103,7 @@ CPPSRCS= \
|
|||
nsPopupSetFrame.cpp \
|
||||
nsTitleBarFrame.cpp \
|
||||
nsResizerFrame.cpp \
|
||||
nsXULTooltipListener.cpp \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
|
@ -158,6 +159,7 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\nsMenuDismissalListener.obj \
|
||||
.\$(OBJDIR)\nsTitleBarFrame.obj \
|
||||
.\$(OBJDIR)\nsResizerFrame.obj \
|
||||
.\$(OBJDIR)\nsXULTooltipListener.obj \
|
||||
$(NULL)
|
||||
|
||||
LINCS= \
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIScrollableView.h"
|
||||
|
@ -132,14 +133,22 @@ nsDocElementBoxFrame::CreateAnonymousContent(nsIPresContext* aPresContext,
|
|||
doc->GetNodeInfoManager(*getter_AddRefs(nodeInfoManager));
|
||||
NS_ENSURE_TRUE(nodeInfoManager, NS_ERROR_FAILURE);
|
||||
|
||||
// create the top-secret popupgroup node. shhhhh!
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nodeInfoManager->GetNodeInfo(NS_LITERAL_STRING("popupgroup"), NS_LITERAL_STRING(""), NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
|
||||
*getter_AddRefs(nodeInfo));
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content));
|
||||
|
||||
aAnonymousItems.AppendElement(content);
|
||||
|
||||
// create the top-secret default tooltip node. shhhhh!
|
||||
nodeInfoManager->GetNodeInfo(NS_LITERAL_STRING("tooltip"), NS_LITERAL_STRING(""), NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"),
|
||||
*getter_AddRefs(nodeInfo));
|
||||
elementFactory->CreateInstanceByTag(nodeInfo, getter_AddRefs(content));
|
||||
content->SetAttr(nsnull, nsXULAtoms::defaultz, NS_LITERAL_STRING("true"), PR_FALSE);
|
||||
aAnonymousItems.AppendElement(content);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
class nsIFrame;
|
||||
class nsIContent;
|
||||
|
||||
// {DF05F6AB-320B-4e06-AFB3-E39E632A7555}
|
||||
#define NS_IROOTBOX_IID \
|
||||
|
@ -54,6 +55,12 @@ public:
|
|||
|
||||
NS_IMETHOD GetPopupSetFrame(nsIFrame** aResult)=0;
|
||||
NS_IMETHOD SetPopupSetFrame(nsIFrame* aPopupSet)=0;
|
||||
|
||||
NS_IMETHOD GetDefaultTooltip(nsIContent** aResult)=0;
|
||||
NS_IMETHOD SetDefaultTooltip(nsIContent* aTooltip)=0;
|
||||
|
||||
NS_IMETHOD AddTooltipSupport(nsIContent* aNode)=0;
|
||||
NS_IMETHOD RemoveTooltipSupport(nsIContent* aNode)=0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -329,7 +329,7 @@ nsPopupSetFrame::ShowPopup(nsIContent* aElementContent, nsIContent* aPopupConten
|
|||
const nsString& aPopupAlignment)
|
||||
{
|
||||
// First fire the popupshowing event.
|
||||
if (!OnCreate(aPopupContent))
|
||||
if (!OnCreate(aXPos, aYPos, aPopupContent))
|
||||
return NS_OK;
|
||||
|
||||
// See if we already have an entry in our list. We must create a new one on a miss.
|
||||
|
@ -373,7 +373,7 @@ nsPopupSetFrame::ShowPopup(nsIContent* aElementContent, nsIContent* aPopupConten
|
|||
OpenPopup(entry, PR_TRUE);
|
||||
|
||||
// Now fire the popupshown event.
|
||||
OnCreated(aPopupContent);
|
||||
OnCreated(aXPos, aYPos, aPopupContent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -520,7 +520,7 @@ nsPopupSetFrame::ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsPopupSetFrame::OnCreate(nsIContent* aPopupContent)
|
||||
nsPopupSetFrame::OnCreate(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
|
@ -532,6 +532,8 @@ nsPopupSetFrame::OnCreate(nsIContent* aPopupContent)
|
|||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
event.point.x = aX;
|
||||
event.point.y = aY;
|
||||
|
||||
if (aPopupContent) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
|
@ -599,7 +601,7 @@ nsPopupSetFrame::OnCreate(nsIContent* aPopupContent)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsPopupSetFrame::OnCreated(nsIContent* aPopupContent)
|
||||
nsPopupSetFrame::OnCreated(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event;
|
||||
|
@ -611,6 +613,8 @@ nsPopupSetFrame::OnCreated(nsIContent* aPopupContent)
|
|||
event.isMeta = PR_FALSE;
|
||||
event.clickCount = 0;
|
||||
event.widget = nsnull;
|
||||
event.point.x = aX;
|
||||
event.point.y = aY;
|
||||
|
||||
if (aPopupContent) {
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
|
|
|
@ -99,9 +99,9 @@ public:
|
|||
NS_IMETHOD AddPopupFrame(nsIFrame* aPopup);
|
||||
NS_IMETHOD RemovePopupFrame(nsIFrame* aPopup);
|
||||
|
||||
PRBool OnCreate(nsIContent* aPopupContent);
|
||||
PRBool OnCreate(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent);
|
||||
PRBool OnDestroy(nsIContent* aPopupContent);
|
||||
PRBool OnCreated(nsIContent* aPopupContent);
|
||||
PRBool OnCreated(PRInt32 aX, PRInt32 aY, nsIContent* aPopupContent);
|
||||
PRBool OnDestroyed(nsIContent* aPopupContent);
|
||||
|
||||
void ActivatePopup(nsPopupFrameList* aEntry, PRBool aActivateFlag);
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
#include "nsBoxFrame.h"
|
||||
#include "nsStackLayout.h"
|
||||
#include "nsIRootBox.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsXULTooltipListener.h"
|
||||
|
||||
// Interface IDs
|
||||
|
||||
|
@ -77,6 +79,10 @@ public:
|
|||
|
||||
NS_IMETHOD GetPopupSetFrame(nsIFrame** aResult);
|
||||
NS_IMETHOD SetPopupSetFrame(nsIFrame* aPopupSet);
|
||||
NS_IMETHOD GetDefaultTooltip(nsIContent** aResult);
|
||||
NS_IMETHOD SetDefaultTooltip(nsIContent* aTooltip);
|
||||
NS_IMETHOD AddTooltipSupport(nsIContent* aNode);
|
||||
NS_IMETHOD RemoveTooltipSupport(nsIContent* aNode);
|
||||
|
||||
NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
|
||||
nsIPresShell& aPresShell,
|
||||
|
@ -123,6 +129,9 @@ public:
|
|||
#endif
|
||||
|
||||
nsIFrame* mPopupSetFrame;
|
||||
|
||||
protected:
|
||||
nsIContent* mDefaultTooltip;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -305,6 +314,41 @@ nsRootBoxFrame::SetPopupSetFrame(nsIFrame* aPopupSet)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRootBoxFrame::GetDefaultTooltip(nsIContent** aTooltip)
|
||||
{
|
||||
*aTooltip = mDefaultTooltip;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
|
||||
{
|
||||
mDefaultTooltip = aTooltip;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
|
||||
{
|
||||
// listener will be refcounted by dom event targets that
|
||||
// it will add itself to, and destroyed when those targets
|
||||
// are destroyed
|
||||
nsXULTooltipListener* listener = new nsXULTooltipListener();
|
||||
listener->Init(aNode, this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRootBoxFrame::RemoveTooltipSupport(nsIContent* aNode)
|
||||
{
|
||||
// XXjh yuck, I'll have to implement a way to get at
|
||||
// the tooltip listener for a given node to make
|
||||
// this work. Not crucial, we aren't removing
|
||||
// tooltips from any nodes in the app just yet.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
nsRootBoxFrame::AddRef(void)
|
||||
{
|
||||
|
|
|
@ -136,6 +136,11 @@ interface nsIOutlinerBoxObject : nsISupports
|
|||
void getCoordsForCellItem(in long row, in wstring colID, in wstring element,
|
||||
out long x, out long y, out long width, out long height);
|
||||
|
||||
/**
|
||||
* Determine if the text of a cell is being cropped or not.
|
||||
*/
|
||||
boolean isCellCropped(in long row, in AString colID);
|
||||
|
||||
/**
|
||||
* The view is responsible for calling these notification methods when
|
||||
* rows are added or removed. Index is the position at which the new
|
||||
|
|
|
@ -1170,6 +1170,95 @@ nsOutlinerBodyFrame::GetItemWithinCellAt(PRInt32 aX, const nsRect& aCellRect,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOutlinerBodyFrame::IsCellCropped(PRInt32 aRow, const nsAString& aColID, PRBool *_retval)
|
||||
{
|
||||
nsOutlinerColumn* currCol = nsnull;
|
||||
// Keep looping until we find a column with a matching Id.
|
||||
for (currCol = mColumns; currCol; currCol = currCol->GetNext()) {
|
||||
nsAutoString colID;
|
||||
currCol->GetID(colID);
|
||||
if (colID.Equals(aColID))
|
||||
break;
|
||||
}
|
||||
|
||||
if (currCol) {
|
||||
// The rect for the current cell.
|
||||
nsRect cellRect(0, 0, currCol->GetWidth(), mRowHeight);
|
||||
|
||||
// Adjust borders and padding for the cell.
|
||||
nsCOMPtr<nsIStyleContext> cellContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinercell, getter_AddRefs(cellContext));
|
||||
AdjustForBorderPadding(cellContext, cellRect);
|
||||
|
||||
nscoord remainWidth = cellRect.width;
|
||||
|
||||
if (currCol->IsPrimary()) {
|
||||
// If the current Column is a Primary, then we need to take into account
|
||||
// the indentation and possibly a twisty.
|
||||
|
||||
// The amount of indentation is the indentation width (|mIndentation|) by the level.
|
||||
PRInt32 level;
|
||||
mView->GetLevel(aRow, &level);
|
||||
remainWidth -= mIndentation * level;
|
||||
|
||||
// Find the twisty rect by computing its size.
|
||||
nsCOMPtr<nsIStyleContext> twistyContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinertwisty, getter_AddRefs(twistyContext));
|
||||
|
||||
// |GetImageSize| returns the rect of the twisty image, including the
|
||||
// borders and padding.
|
||||
nsRect twistyImageRect = GetImageSize(aRow, currCol->GetID(), twistyContext);
|
||||
|
||||
// Add in the margins of the twisty element.
|
||||
const nsStyleMargin* twistyMarginData = (const nsStyleMargin*) twistyContext->GetStyleData(eStyleStruct_Margin);
|
||||
nsMargin twistyMargin;
|
||||
twistyMarginData->GetMargin(twistyMargin);
|
||||
twistyImageRect.Inflate(twistyMargin);
|
||||
|
||||
remainWidth -= twistyImageRect.width;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStyleContext> imageContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinerimage, getter_AddRefs(imageContext));
|
||||
|
||||
// Account for the width of the cell image.
|
||||
nsRect imageSize = GetImageSize(aRow, currCol->GetID(), imageContext);
|
||||
remainWidth -= imageSize.width;
|
||||
|
||||
// Get the cell text.
|
||||
nsXPIDLString text;
|
||||
mView->GetCellText(aRow, currCol->GetID(), getter_Copies(text));
|
||||
nsAutoString cellText(text);
|
||||
|
||||
nsCOMPtr<nsIStyleContext> textContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinercelltext, getter_AddRefs(textContext));
|
||||
|
||||
// Get the borders and padding for the text.
|
||||
nsStyleBorderPadding borderPadding;
|
||||
textContext->GetBorderPaddingFor(borderPadding);
|
||||
nsMargin bp(0,0,0,0);
|
||||
borderPadding.GetBorderPadding(bp);
|
||||
|
||||
// Get the font style for the text and pass it to the rendering context.
|
||||
const nsStyleFont* fontStyle = (const nsStyleFont*) textContext->GetStyleData(eStyleStruct_Font);
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
shell->CreateRenderingContext(this, getter_AddRefs(rc));
|
||||
rc->SetFont(fontStyle->mFont);
|
||||
|
||||
// Get the width of the text itself
|
||||
nscoord width;
|
||||
rc->GetWidth(cellText, width);
|
||||
nscoord totalTextWidth = width + bp.left + bp.right;
|
||||
|
||||
// If |totalTextWidth| is greater than |remainWidth|, then we are cropping.
|
||||
*_retval = totalTextWidth > remainWidth;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsOutlinerBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCount)
|
||||
{
|
||||
|
@ -2441,7 +2530,10 @@ nsOutlinerBodyFrame::EnsureColumns()
|
|||
frame->GetParent(&colContainer);
|
||||
} while (!frame);
|
||||
|
||||
nsCOMPtr<nsIBox> colContainerBox(do_QueryInterface(colContainer));
|
||||
if (!colContainer)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIBox> colContainerBox(do_QueryInterface(colContainer));
|
||||
nsIBox* colBox = nsnull;
|
||||
colContainerBox->GetChildBox(&colBox);
|
||||
|
||||
|
|
|
@ -354,6 +354,15 @@ nsOutlinerBoxObject::GetCoordsForCellItem(PRInt32 aRow, const PRUnichar *aColID,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOutlinerBoxObject::IsCellCropped(PRInt32 aRow, const nsAString& aColID, PRBool *_retval)
|
||||
{
|
||||
nsIOutlinerBoxObject* body = GetOutlinerBody();
|
||||
if (body)
|
||||
return body->IsCellCropped(aRow, aColID, _retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsOutlinerBoxObject::RowCountChanged(PRInt32 aIndex, PRInt32 aDelta)
|
||||
{
|
||||
nsIOutlinerBoxObject* body = GetOutlinerBody();
|
||||
|
|
|
@ -136,6 +136,11 @@ interface nsIOutlinerBoxObject : nsISupports
|
|||
void getCoordsForCellItem(in long row, in wstring colID, in wstring element,
|
||||
out long x, out long y, out long width, out long height);
|
||||
|
||||
/**
|
||||
* Determine if the text of a cell is being cropped or not.
|
||||
*/
|
||||
boolean isCellCropped(in long row, in AString colID);
|
||||
|
||||
/**
|
||||
* The view is responsible for calling these notification methods when
|
||||
* rows are added or removed. Index is the position at which the new
|
||||
|
|
|
@ -1170,6 +1170,95 @@ nsOutlinerBodyFrame::GetItemWithinCellAt(PRInt32 aX, const nsRect& aCellRect,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOutlinerBodyFrame::IsCellCropped(PRInt32 aRow, const nsAString& aColID, PRBool *_retval)
|
||||
{
|
||||
nsOutlinerColumn* currCol = nsnull;
|
||||
// Keep looping until we find a column with a matching Id.
|
||||
for (currCol = mColumns; currCol; currCol = currCol->GetNext()) {
|
||||
nsAutoString colID;
|
||||
currCol->GetID(colID);
|
||||
if (colID.Equals(aColID))
|
||||
break;
|
||||
}
|
||||
|
||||
if (currCol) {
|
||||
// The rect for the current cell.
|
||||
nsRect cellRect(0, 0, currCol->GetWidth(), mRowHeight);
|
||||
|
||||
// Adjust borders and padding for the cell.
|
||||
nsCOMPtr<nsIStyleContext> cellContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinercell, getter_AddRefs(cellContext));
|
||||
AdjustForBorderPadding(cellContext, cellRect);
|
||||
|
||||
nscoord remainWidth = cellRect.width;
|
||||
|
||||
if (currCol->IsPrimary()) {
|
||||
// If the current Column is a Primary, then we need to take into account
|
||||
// the indentation and possibly a twisty.
|
||||
|
||||
// The amount of indentation is the indentation width (|mIndentation|) by the level.
|
||||
PRInt32 level;
|
||||
mView->GetLevel(aRow, &level);
|
||||
remainWidth -= mIndentation * level;
|
||||
|
||||
// Find the twisty rect by computing its size.
|
||||
nsCOMPtr<nsIStyleContext> twistyContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinertwisty, getter_AddRefs(twistyContext));
|
||||
|
||||
// |GetImageSize| returns the rect of the twisty image, including the
|
||||
// borders and padding.
|
||||
nsRect twistyImageRect = GetImageSize(aRow, currCol->GetID(), twistyContext);
|
||||
|
||||
// Add in the margins of the twisty element.
|
||||
const nsStyleMargin* twistyMarginData = (const nsStyleMargin*) twistyContext->GetStyleData(eStyleStruct_Margin);
|
||||
nsMargin twistyMargin;
|
||||
twistyMarginData->GetMargin(twistyMargin);
|
||||
twistyImageRect.Inflate(twistyMargin);
|
||||
|
||||
remainWidth -= twistyImageRect.width;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStyleContext> imageContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinerimage, getter_AddRefs(imageContext));
|
||||
|
||||
// Account for the width of the cell image.
|
||||
nsRect imageSize = GetImageSize(aRow, currCol->GetID(), imageContext);
|
||||
remainWidth -= imageSize.width;
|
||||
|
||||
// Get the cell text.
|
||||
nsXPIDLString text;
|
||||
mView->GetCellText(aRow, currCol->GetID(), getter_Copies(text));
|
||||
nsAutoString cellText(text);
|
||||
|
||||
nsCOMPtr<nsIStyleContext> textContext;
|
||||
GetPseudoStyleContext(nsXULAtoms::mozoutlinercelltext, getter_AddRefs(textContext));
|
||||
|
||||
// Get the borders and padding for the text.
|
||||
nsStyleBorderPadding borderPadding;
|
||||
textContext->GetBorderPaddingFor(borderPadding);
|
||||
nsMargin bp(0,0,0,0);
|
||||
borderPadding.GetBorderPadding(bp);
|
||||
|
||||
// Get the font style for the text and pass it to the rendering context.
|
||||
const nsStyleFont* fontStyle = (const nsStyleFont*) textContext->GetStyleData(eStyleStruct_Font);
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mPresContext->GetShell(getter_AddRefs(shell));
|
||||
nsCOMPtr<nsIRenderingContext> rc;
|
||||
shell->CreateRenderingContext(this, getter_AddRefs(rc));
|
||||
rc->SetFont(fontStyle->mFont);
|
||||
|
||||
// Get the width of the text itself
|
||||
nscoord width;
|
||||
rc->GetWidth(cellText, width);
|
||||
nscoord totalTextWidth = width + bp.left + bp.right;
|
||||
|
||||
// If |totalTextWidth| is greater than |remainWidth|, then we are cropping.
|
||||
*_retval = totalTextWidth > remainWidth;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsOutlinerBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCount)
|
||||
{
|
||||
|
@ -2441,7 +2530,10 @@ nsOutlinerBodyFrame::EnsureColumns()
|
|||
frame->GetParent(&colContainer);
|
||||
} while (!frame);
|
||||
|
||||
nsCOMPtr<nsIBox> colContainerBox(do_QueryInterface(colContainer));
|
||||
if (!colContainer)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIBox> colContainerBox(do_QueryInterface(colContainer));
|
||||
nsIBox* colBox = nsnull;
|
||||
colContainerBox->GetChildBox(&colBox);
|
||||
|
||||
|
|
|
@ -354,6 +354,15 @@ nsOutlinerBoxObject::GetCoordsForCellItem(PRInt32 aRow, const PRUnichar *aColID,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOutlinerBoxObject::IsCellCropped(PRInt32 aRow, const nsAString& aColID, PRBool *_retval)
|
||||
{
|
||||
nsIOutlinerBoxObject* body = GetOutlinerBody();
|
||||
if (body)
|
||||
return body->IsCellCropped(aRow, aColID, _retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsOutlinerBoxObject::RowCountChanged(PRInt32 aIndex, PRInt32 aDelta)
|
||||
{
|
||||
nsIOutlinerBoxObject* body = GetOutlinerBody();
|
||||
|
|
Загрузка…
Ссылка в новой задаче