Changing CreatePopup to return the popup. Adding a bunch of stuff for tooltips to the popup code. Fixing some bugs in webshell with loading malformed popups. Renamed "popup" to "popupElement" in the document and added "tooltipElement" as well.

This commit is contained in:
pinkerton%netscape.com 1999-07-01 00:07:41 +00:00
parent 957d5a4f73
commit 358bcc130a
24 changed files with 975 additions and 186 deletions

View File

@ -34,6 +34,8 @@
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsIDOMUIEvent.h"
#include "nsITimer.h"
////////////////////////////////////////////////////////////////////////
@ -41,10 +43,6 @@ static NS_DEFINE_IID(kXULPopupListenerCID, NS_XULPOPUPLISTENER_CID);
static NS_DEFINE_IID(kIXULPopupListenerIID, NS_IXULPOPUPLISTENER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDomNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDomEventListenerIID, NS_IDOMEVENTLISTENER_IID);
////////////////////////////////////////////////////////////////////////
// PopupListenerImpl
//
@ -71,8 +69,8 @@ public:
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) ;
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) ;
// nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent) { return NS_OK; };
@ -82,16 +80,35 @@ public:
virtual nsresult HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
protected:
virtual nsresult LaunchPopup(nsIDOMEvent* anEvent);
virtual nsresult LaunchPopup( nsIDOMElement* aElement, PRInt32 aScreenX, PRInt32 aScreenY,
PRInt32 aClientX, PRInt32 aClientY ) ;
nsresult FindDocumentForNode ( nsIDOMNode* inNode, nsIDOMXULDocument** outDoc ) ;
private:
nsIDOMElement* element; // Weak reference. The element will go away first.
// |mElement| is the node to which this listener is attached.
nsIDOMElement* mElement; // Weak ref. The element will go away first.
XULPopupType popupType;
nsCOMPtr<nsIDOMWindow> mPopup; // The popup. We are responsible for making it go away.
// The following members are not used unless |popupType| is tooltip.
// a timer for determining if a tooltip should be displayed.
static void sTooltipCallback ( nsITimer *aTimer, void *aClosure ) ;
nsCOMPtr<nsITimer> mTooltipTimer;
PRInt32 mMouseLocX, mMouseLocY; // mouse coordinates for tooltip event
// 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.
nsIDOMNode* mPossibleTooltipNode; // weak ref.
};
////////////////////////////////////////////////////////////////////////
XULPopupListenerImpl::XULPopupListenerImpl(void)
: mElement(nsnull), mPossibleTooltipNode(nsnull), mMouseLocX(0), mMouseLocY(0)
{
NS_INIT_REFCNT();
@ -99,6 +116,11 @@ XULPopupListenerImpl::XULPopupListenerImpl(void)
XULPopupListenerImpl::~XULPopupListenerImpl(void)
{
//XXX do we need to close the popup here? Will we get the right events as
//XXX the topLevel window is going away when the closebox is pressed?
if ( mPopup )
mPopup->Close();
}
NS_IMPL_ADDREF(XULPopupListenerImpl)
@ -126,7 +148,7 @@ XULPopupListenerImpl::QueryInterface(REFNSIID iid, void** result)
NS_ADDREF_THIS();
return NS_OK;
}
else if (iid.Equals(kIDomEventListenerIID)) {
else if (iid.Equals(nsIDOMEventListener::GetIID())) {
*result = (nsIDOMEventListener*)(nsIDOMMouseListener*)this;
NS_ADDREF_THIS();
return NS_OK;
@ -138,7 +160,7 @@ XULPopupListenerImpl::QueryInterface(REFNSIID iid, void** result)
NS_IMETHODIMP
XULPopupListenerImpl::Init(nsIDOMElement* aElement, const XULPopupType& popup)
{
element = aElement; // Weak reference. Don't addref it.
mElement = aElement; // Weak reference. Don't addref it.
popupType = popup;
return NS_OK;
}
@ -187,24 +209,186 @@ XULPopupListenerImpl::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
//
// MouseOver
//
// If we're a tooltip, fire off a timer to see if a tooltip should be shown.
//
nsresult
XULPopupListenerImpl::LaunchPopup(nsIDOMEvent* anEvent)
XULPopupListenerImpl::MouseOver(nsIDOMEvent* aMouseEvent)
{
nsresult rv = NS_OK;
// make sure we're a tooltip. if not, bail.
if ( popupType != eXULPopupType_tooltip )
return NS_OK;
//XXX recognize when a popup is already up and immediately show the
//XXX tooltip for the new item if the dom element is different than
//XXX the element for which we are currently displaying the tip.
//XXX
//XXX for now, just be stupid to get things working.
// Kill off an old timer and create a new one.
if ( mTooltipTimer ) {
mTooltipTimer->Cancel();
mTooltipTimer = nsnull;
}
NS_NewTimer ( getter_AddRefs(mTooltipTimer) );
if ( mTooltipTimer ) {
nsCOMPtr<nsIDOMUIEvent> uiEvent ( do_QueryInterface(aMouseEvent) );
if ( uiEvent ) {
// stash the coordinates of the event so that we can still get back to it from within the
// timer scallback. Also stash the node that started this so we can put it into the
// document later on (if the timer ever fires).
nsCOMPtr<nsIDOMNode> eventTarget;
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
mPossibleTooltipNode = eventTarget.get();
// BUG: 8598, widget and mouse coords not set for MouseOver events.
// uiEvent->GetScreenX(&mMouseLocX);
// uiEvent->GetScreenY(&mMouseLocY);
mMouseLocX = 50; mMouseLocY = 50; // XXX until bug 8598 fixed
mTooltipTimer->Init(sTooltipCallback, this, 1000); // one second delay
}
}
else
NS_WARNING ( "Could not create a timer for tooltip tracking" );
return NS_OK;
} // MouseOver
//
// 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;
if ( mTooltipTimer )
mTooltipTimer->Cancel();
if ( mPopup ) {
mPopup->Close(); // hide the popup
mPopup = nsnull; // release the popup
// clear out the tooltip node on the document
nsCOMPtr<nsIDOMNode> eventTarget;
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
nsCOMPtr<nsIDOMXULDocument> doc;
FindDocumentForNode ( eventTarget, getter_AddRefs(doc) );
if ( doc )
doc->SetTooltipElement(nsnull);
}
return NS_OK;
} // MouseOut
//
// 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 (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
NS_ERROR("Unable to retrieve the document.");
return rv;
}
// Turn the document into a XUL document so we can use getElementById
nsCOMPtr<nsIDOMXULDocument> xulDocument = do_QueryInterface(document);
if (xulDocument == nsnull) {
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
//
nsresult
XULPopupListenerImpl::LaunchPopup ( nsIDOMEvent* anEvent )
{
// Retrieve our x and y position.
nsCOMPtr<nsIDOMUIEvent> uiEvent ( do_QueryInterface(anEvent) );
if (!uiEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
PRInt32 xPos, yPos;
uiEvent->GetScreenX(&xPos);
uiEvent->GetScreenY(&yPos);
PRInt32 offsetX, offsetY;
uiEvent->GetClientX(&offsetX);
uiEvent->GetClientY(&offsetY);
return LaunchPopup ( mElement, xPos, yPos, offsetX, offsetY );
}
//
// LaunchPopup
//
// Given the element on which the event was triggered and the mouse locations in
// screen and widget coordinates, popup a new window showing the appropriate
// 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
// the popup content in the document.
//
nsresult
XULPopupListenerImpl::LaunchPopup( nsIDOMElement* aElement, PRInt32 aScreenX, PRInt32 aScreenY,
PRInt32 aOffsetX, PRInt32 aOffsetY )
{
nsresult rv = NS_OK;
nsAutoString type("popup");
if (eXULPopupType_context == popupType)
if ( popupType == eXULPopupType_context )
type = "context";
else if ( popupType == eXULPopupType_tooltip )
type = "tooltip";
nsAutoString identifier;
element->GetAttribute(type, identifier);
mElement->GetAttribute(type, identifier);
if (identifier == "")
return rv;
// Try to find the popup content.
// 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.
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
if (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
NS_ERROR("Unable to retrieve the document.");
return rv;
@ -219,17 +403,15 @@ XULPopupListenerImpl::LaunchPopup(nsIDOMEvent* anEvent)
// XXX Handle the _child case for popups and context menus!
// Use getElementById to obtain the popup content.
// Use getElementById to obtain the popup content and gracefully fail if
// we didn't find any popup content in the document.
nsCOMPtr<nsIDOMElement> popupContent;
if (NS_FAILED(rv = xulDocument->GetElementById(identifier, getter_AddRefs(popupContent)))) {
NS_ERROR("GetElementById had some kind of spasm.");
return rv;
}
if (popupContent == nsnull) {
// Gracefully fail in this case.
if ( !popupContent )
return NS_OK;
}
// We have some popup content. Obtain our window.
nsIScriptContextOwner* owner = document->GetScriptContextOwner();
@ -242,42 +424,30 @@ XULPopupListenerImpl::LaunchPopup(nsIDOMEvent* anEvent)
if (domWindow != nsnull) {
// Find out if we're anchored.
nsAutoString anchorAlignment("none");
element->GetAttribute("popupanchor", anchorAlignment);
mElement->GetAttribute("popupanchor", anchorAlignment);
nsAutoString popupAlignment("topleft");
element->GetAttribute("popupalign", popupAlignment);
mElement->GetAttribute("popupalign", popupAlignment);
// Set the popup in the document for the duration of this call.
xulDocument->SetPopup(element);
// Set the popup in the document for the duration of this call.
xulDocument->SetPopupElement(mElement);
// Retrieve our x and y position.
nsCOMPtr<nsIDOMUIEvent>uiEvent;
uiEvent = do_QueryInterface(anEvent);
if (!uiEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
PRInt32 xPos, yPos;
uiEvent->GetScreenX(&xPos);
uiEvent->GetScreenY(&yPos);
// If we're anchored, we pass in client/screen offsets so that
// we can translate the frames corners to screen coords.
// we can translate the frames corners to screen coords.
PRInt32 xPos = aScreenX, yPos = aScreenY;
if (anchorAlignment != "none") {
PRInt32 offsetX, offsetY;
uiEvent->GetClientX(&offsetX);
uiEvent->GetClientY(&offsetY);
xPos = xPos-offsetX;
yPos = yPos-offsetY;
xPos -= aOffsetX;
yPos -= aOffsetY;
}
domWindow->CreatePopup(element, popupContent,
xPos, yPos,
type, anchorAlignment, popupAlignment);
domWindow->CreatePopup(mElement, popupContent,
xPos, yPos,
type, anchorAlignment, popupAlignment,
getter_AddRefs(mPopup));
if ( popupType == eXULPopupType_popup && mPopup )
mPopup->Focus();
// XXX For menus only, clear the document.popup field.
}
}
NS_RELEASE(global);
}
}
@ -290,10 +460,12 @@ nsresult
XULPopupListenerImpl::Blur(nsIDOMEvent* aMouseEvent)
{
nsresult rv = NS_OK;
#if 0
// ONLY NEEDED BECAUSE HYATT WAS LAZY
// Try to find the popup content.
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
if (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
NS_ERROR("Unable to retrieve the document.");
return rv;
@ -319,7 +491,20 @@ XULPopupListenerImpl::Blur(nsIDOMEvent* aMouseEvent)
domWindow->Close();
}
}
#endif
// Blur events don't bubble, so this means our window lost focus.
// Let's check just to make sure.
nsCOMPtr<nsIDOMNode> eventTarget;
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
// Close, but only if we are the same target.
nsCOMPtr<nsIDOMNode> windowNode = do_QueryInterface(mPopup);
if (windowNode.get() == eventTarget.get()) {
mPopup->Close();
mPopup = nsnull;
}
// XXX Figure out how to fire the DESTROY event for the
// arbitrary XUL case
@ -329,6 +514,40 @@ XULPopupListenerImpl::Blur(nsIDOMEvent* aMouseEvent)
return rv;
}
//
// 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 |aClosure| object passed to
// us by the timer:
// -- the x/y coordinates of the mouse
// -- the dom node the user hovered over
//
void
XULPopupListenerImpl :: sTooltipCallback (nsITimer *aTimer, void *aClosure)
{
XULPopupListenerImpl* self = NS_STATIC_CAST(XULPopupListenerImpl*, aClosure);
if ( self ) {
// set the node in the document that triggered the tooltip and show it
nsCOMPtr<nsIDOMXULDocument> doc;
self->FindDocumentForNode ( self->mPossibleTooltipNode, getter_AddRefs(doc) );
if ( doc ) {
nsCOMPtr<nsIDOMElement> element ( do_QueryInterface(self->mPossibleTooltipNode) );
if ( element ) {
doc->SetTooltipElement ( element );
self->LaunchPopup ( element, self->mMouseLocX, self->mMouseLocY, 0, 0 );
}
} // if document
} // if "self" data valid
} // sTimerCallback
////////////////////////////////////////////////////////////////
nsresult
NS_NewXULPopupListener(nsIXULPopupListener** pop)

View File

@ -782,10 +782,20 @@ protected:
nsString mCommand;
nsCOMPtr<nsIRDFResource> mFragmentRoot; // [OWNER]
nsVoidArray mSubDocuments; // [OWNER] of subelements
nsCOMPtr<nsIDOMElement> mPopup; // [OWNER] of this popup element in the doc
PRBool mIsPopup;
nsCOMPtr<nsIDOMHTMLFormElement> mHiddenForm; // [OWNER] of this content element
nsCOMPtr<nsIDOMXULFocusTracker> mFocusTracker; // [OWNER] of the focus tracker
// The following are pointers into the content model which provide access to
// the objects triggering either a popup or a tooltip. These are marked as
// [OWNER] only because someone could, through DOM calls, delete the object from the
// content model while the popup/tooltip was visible. If we didn't have a reference
// to it, the object would go away and we'd be left pointing to garbage. This
// does not introduce cycles into the ownership model because this is still
// parent/child ownership. Just wanted the reader to know hyatt and I had thought about
// this (pinkerton).
nsCOMPtr<nsIDOMElement> mPopupElement; // [OWNER] element triggering the popup
nsCOMPtr<nsIDOMElement> mTooltipElement; // [OWNER] element triggering the tooltip
};
PRInt32 XULDocumentImpl::gRefCnt = 0;
@ -2902,20 +2912,37 @@ XULDocumentImpl::CreateRange(nsIDOMRange** aRange)
// nsIDOMXULDocument interface
NS_IMETHODIMP
XULDocumentImpl::GetPopup(nsIDOMElement** anElement)
XULDocumentImpl::GetPopupElement(nsIDOMElement** anElement)
{
*anElement = mPopup;
*anElement = mPopupElement;
NS_IF_ADDREF(*anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::SetPopup(nsIDOMElement* anElement)
XULDocumentImpl::SetPopupElement(nsIDOMElement* anElement)
{
mPopup = dont_QueryInterface(anElement);
mPopupElement = dont_QueryInterface(anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::GetTooltipElement(nsIDOMElement** anElement)
{
*anElement = mTooltipElement;
NS_IF_ADDREF(*anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::SetTooltipElement(nsIDOMElement* anElement)
{
mTooltipElement = dont_QueryInterface(anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::GetFocus(nsIDOMXULFocusTracker** aTracker)
{
@ -3128,7 +3155,7 @@ XULDocumentImpl::CreatePopupDocument(nsIContent* aPopupElement, nsIDocument** aR
popupDoc->mNameSpaceManager = mNameSpaceManager;
// We share the mPopup
popupDoc->mPopup = mPopup;
popupDoc->mPopupElement = mPopupElement;
// Suck all of the root's content into our document.
// We need to make the XUL builder instantiate this node.

View File

@ -266,7 +266,7 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow);
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup);
NS_IMETHOD FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult);
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken);
@ -2198,12 +2198,12 @@ nsWebShell::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent,
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow)
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup)
{
if (nsnull != mContainer) {
return mContainer->CreatePopup(aElement, aPopupContent, aXPos, aYPos, aPopupType,
anAnchorAlignment, aPopupAlignment,
aWindow);
aWindow, outPopup);
}
return NS_OK;
}

View File

@ -158,7 +158,7 @@ public:
NS_IMETHOD SetInterval(JSContext *cx, jsval *argv, PRUint32 argc, PRInt32* aReturn)=0;
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment)=0;
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment, nsIDOMWindow** aReturn)=0;
NS_IMETHOD Open(JSContext *cx, jsval *argv, PRUint32 argc, nsIDOMWindow** aReturn)=0;
@ -231,7 +231,7 @@ public:
NS_IMETHOD ClearInterval(PRInt32 aTimerID); \
NS_IMETHOD SetTimeout(JSContext *cx, jsval *argv, PRUint32 argc, PRInt32* aReturn); \
NS_IMETHOD SetInterval(JSContext *cx, jsval *argv, PRUint32 argc, PRInt32* aReturn); \
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment); \
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment, nsIDOMWindow** aReturn); \
NS_IMETHOD Open(JSContext *cx, jsval *argv, PRUint32 argc, nsIDOMWindow** aReturn); \
NS_IMETHOD OpenDialog(JSContext *cx, jsval *argv, PRUint32 argc, nsIDOMWindow** aReturn); \
@ -302,7 +302,7 @@ public:
NS_IMETHOD ClearInterval(PRInt32 aTimerID) { return _to ClearInterval(aTimerID); } \
NS_IMETHOD SetTimeout(JSContext *cx, jsval *argv, PRUint32 argc, PRInt32* aReturn) { return _to SetTimeout(cx, argv, argc, aReturn); } \
NS_IMETHOD SetInterval(JSContext *cx, jsval *argv, PRUint32 argc, PRInt32* aReturn) { return _to SetInterval(cx, argv, argc, aReturn); } \
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment) { return _to CreatePopup(aElement, aPopupContent, aXPos, aYPos, aPopupType, aAnchorAlignment, aPopupAlignment); } \
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, PRInt32 aXPos, PRInt32 aYPos, const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment, nsIDOMWindow** aReturn) { return _to CreatePopup(aElement, aPopupContent, aXPos, aYPos, aPopupType, aAnchorAlignment, aPopupAlignment, aReturn); } \
NS_IMETHOD Open(JSContext *cx, jsval *argv, PRUint32 argc, nsIDOMWindow** aReturn) { return _to Open(cx, argv, argc, aReturn); } \
NS_IMETHOD OpenDialog(JSContext *cx, jsval *argv, PRUint32 argc, nsIDOMWindow** aReturn) { return _to OpenDialog(cx, argv, argc, aReturn); } \

View File

@ -57,11 +57,11 @@
long setTimeout(/* ... */);
long setInterval(/* ... */);
void createPopup(in Element element, in Element popupContent,
in long xPos, in long yPos,
in DOMString popupType, in DOMString anchorAlignment,
in DOMString popupAlignment);
Window createPopup(in Element element, in Element popupContent,
in long xPos, in long yPos,
in DOMString popupType, in DOMString anchorAlignment,
in DOMString popupAlignment);
Window open(/* ... */);
Window openDialog(/* ... */);
};

View File

@ -3,7 +3,9 @@ interface XULDocument : Document {
/* IID: { 0x17ddd8c0, 0xc5f8, 0x11d2, \
{ 0xa6, 0xae, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } */
attribute Element popup;
attribute Element popupElement;
attribute Element tooltipElement;
readonly attribute XULFocusTracker focus;
Element getElementById(in DOMString id);

View File

@ -37,8 +37,11 @@ class nsIDOMXULDocument : public nsIDOMDocument {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMXULDOCUMENT_IID; return iid; }
NS_IMETHOD GetPopup(nsIDOMElement** aPopup)=0;
NS_IMETHOD SetPopup(nsIDOMElement* aPopup)=0;
NS_IMETHOD GetPopupElement(nsIDOMElement** aPopupElement)=0;
NS_IMETHOD SetPopupElement(nsIDOMElement* aPopupElement)=0;
NS_IMETHOD GetTooltipElement(nsIDOMElement** aTooltipElement)=0;
NS_IMETHOD SetTooltipElement(nsIDOMElement* aTooltipElement)=0;
NS_IMETHOD GetFocus(nsIDOMXULFocusTracker** aFocus)=0;
@ -49,8 +52,10 @@ public:
#define NS_DECL_IDOMXULDOCUMENT \
NS_IMETHOD GetPopup(nsIDOMElement** aPopup); \
NS_IMETHOD SetPopup(nsIDOMElement* aPopup); \
NS_IMETHOD GetPopupElement(nsIDOMElement** aPopupElement); \
NS_IMETHOD SetPopupElement(nsIDOMElement* aPopupElement); \
NS_IMETHOD GetTooltipElement(nsIDOMElement** aTooltipElement); \
NS_IMETHOD SetTooltipElement(nsIDOMElement* aTooltipElement); \
NS_IMETHOD GetFocus(nsIDOMXULFocusTracker** aFocus); \
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn); \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn); \
@ -58,8 +63,10 @@ public:
#define NS_FORWARD_IDOMXULDOCUMENT(_to) \
NS_IMETHOD GetPopup(nsIDOMElement** aPopup) { return _to GetPopup(aPopup); } \
NS_IMETHOD SetPopup(nsIDOMElement* aPopup) { return _to SetPopup(aPopup); } \
NS_IMETHOD GetPopupElement(nsIDOMElement** aPopupElement) { return _to GetPopupElement(aPopupElement); } \
NS_IMETHOD SetPopupElement(nsIDOMElement* aPopupElement) { return _to SetPopupElement(aPopupElement); } \
NS_IMETHOD GetTooltipElement(nsIDOMElement** aTooltipElement) { return _to GetTooltipElement(aTooltipElement); } \
NS_IMETHOD SetTooltipElement(nsIDOMElement* aTooltipElement) { return _to SetTooltipElement(aTooltipElement); } \
NS_IMETHOD GetFocus(nsIDOMXULFocusTracker** aFocus) { return _to GetFocus(aFocus); } \
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn) { return _to GetElementById(aId, aReturn); } \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn) { return _to GetElementsByAttribute(aName, aValue, aReturn); } \

View File

@ -2079,14 +2079,15 @@ NS_IMETHODIMP
GlobalWindowImpl::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent,
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType,
const nsString& anAnchorAlignment, const nsString& aPopupAlignment)
const nsString& anAnchorAlignment, const nsString& aPopupAlignment,
nsIDOMWindow** outPopup)
{
if (nsnull != mWebShell) {
// Pass this off to the parent.
nsCOMPtr<nsIWebShellContainer> webShellContainer = do_QueryInterface(mWebShell);
if (webShellContainer) {
webShellContainer->CreatePopup(aElement, aPopupContent, aXPos, aYPos, aPopupType,
anAnchorAlignment, aPopupAlignment, this);
anAnchorAlignment, aPopupAlignment, this, outPopup);
}
}
return NS_OK;

View File

@ -165,7 +165,7 @@ public:
NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent,
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment);
const nsString& aPopupAlignment, nsIDOMWindow** outPopup);
// nsIDOMEventCapturer interface
NS_IMETHOD CaptureEvent(const nsString& aType);

View File

@ -2083,6 +2083,7 @@ WindowCreatePopup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *
{
nsIDOMWindow *nativeThis = (nsIDOMWindow*)nsJSUtils::nsGetNativeThis(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMWindow* nativeRet;
nsIDOMElementPtr b0;
nsIDOMElementPtr b1;
PRInt32 b2;
@ -2147,11 +2148,11 @@ WindowCreatePopup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *
nsJSUtils::nsConvertJSValToString(b6, cx, argv[6]);
if (NS_OK != nativeThis->CreatePopup(b0, b1, b2, b3, b4, b5, b6)) {
if (NS_OK != nativeThis->CreatePopup(b0, b1, b2, b3, b4, b5, b6, &nativeRet)) {
return JS_FALSE;
}
*rval = JSVAL_VOID;
nsJSUtils::nsConvertObjectToJSVal(nativeRet, cx, rval);
}
else {
JS_ReportError(cx, "Function createPopup requires 7 parameters");

View File

@ -50,8 +50,12 @@ NS_DEF_PTR(nsIDOMNodeList);
// XULDocument property ids
//
enum XULDocument_slots {
XULDOCUMENT_POPUP = -1,
XULDOCUMENT_FOCUS = -2
XULDOCUMENT_POPUPELEMENT = -1,
XULDOCUMENT_TOOLTIPELEMENT = -2,
XULDOCUMENT_FOCUS = -3
};
/***********************************************************************/
@ -61,30 +65,88 @@ enum XULDocument_slots {
PR_STATIC_CALLBACK(JSBool)
GetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULDocument *a = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *a = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx);
nsIScriptSecurityManager *secMan;
PRBool ok;
PRBool ok = PR_FALSE;
if (NS_OK != scriptCX->GetSecurityManager(&secMan)) {
return JS_FALSE;
}
switch(JSVAL_TO_INT(id)) {
case XULDOCUMENT_POPUP:
case XULDOCUMENT_POPUPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popup", &ok);
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popupelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (NS_OK == a->GetPopup(&prop)) {
if (NS_OK == a->GetPopupElement(&prop)) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, vp);
}
else {
return JS_FALSE;
}
break;
}
case XULDOCUMENT_TOOLTIPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.tooltipelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (NS_OK == a->GetTooltipElement(&prop)) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, vp);
}
@ -129,36 +191,102 @@ GetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
PR_STATIC_CALLBACK(JSBool)
SetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULDocument *a = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *a = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx);
nsIScriptSecurityManager *secMan;
PRBool ok;
PRBool ok = PR_FALSE;
if (NS_OK != scriptCX->GetSecurityManager(&secMan)) {
return JS_FALSE;
}
switch(JSVAL_TO_INT(id)) {
case XULDOCUMENT_POPUP:
case XULDOCUMENT_POPUPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popup", &ok);
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popupelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIElementIID, "Element",
cx, *vp)) {
return JS_FALSE;
}
a->SetPopup(prop);
a->SetPopupElement(prop);
NS_IF_RELEASE(prop);
break;
}
case XULDOCUMENT_TOOLTIPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.tooltipelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIElementIID, "Element",
cx, *vp)) {
return JS_FALSE;
}
a->SetTooltipElement(prop);
NS_IF_RELEASE(prop);
break;
}
@ -211,7 +339,8 @@ ResolveXULDocument(JSContext *cx, JSObject *obj, jsval id)
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMElement* nativeRet;
nsAutoString b0;
@ -263,7 +392,8 @@ XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementsByAttribute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMNodeList* nativeRet;
nsAutoString b0;
@ -335,7 +465,10 @@ JSClass XULDocumentClass = {
//
static JSPropertySpec XULDocumentProperties[] =
{
{"popup", XULDOCUMENT_POPUP, JSPROP_ENUMERATE},
{"popupElement", XULDOCUMENT_POPUPELEMENT, JSPROP_ENUMERATE},
{"tooltipElement", XULDOCUMENT_TOOLTIPELEMENT, JSPROP_ENUMERATE},
{"focus", XULDOCUMENT_FOCUS, JSPROP_ENUMERATE | JSPROP_READONLY},
{0}
};

View File

@ -3,7 +3,9 @@ interface XULDocument : Document {
/* IID: { 0x17ddd8c0, 0xc5f8, 0x11d2, \
{ 0xa6, 0xae, 0x0, 0x10, 0x4b, 0xde, 0x60, 0x48 } } */
attribute Element popup;
attribute Element popupElement;
attribute Element tooltipElement;
readonly attribute XULFocusTracker focus;
Element getElementById(in DOMString id);

View File

@ -37,8 +37,11 @@ class nsIDOMXULDocument : public nsIDOMDocument {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IDOMXULDOCUMENT_IID; return iid; }
NS_IMETHOD GetPopup(nsIDOMElement** aPopup)=0;
NS_IMETHOD SetPopup(nsIDOMElement* aPopup)=0;
NS_IMETHOD GetPopupElement(nsIDOMElement** aPopupElement)=0;
NS_IMETHOD SetPopupElement(nsIDOMElement* aPopupElement)=0;
NS_IMETHOD GetTooltipElement(nsIDOMElement** aTooltipElement)=0;
NS_IMETHOD SetTooltipElement(nsIDOMElement* aTooltipElement)=0;
NS_IMETHOD GetFocus(nsIDOMXULFocusTracker** aFocus)=0;
@ -49,8 +52,10 @@ public:
#define NS_DECL_IDOMXULDOCUMENT \
NS_IMETHOD GetPopup(nsIDOMElement** aPopup); \
NS_IMETHOD SetPopup(nsIDOMElement* aPopup); \
NS_IMETHOD GetPopupElement(nsIDOMElement** aPopupElement); \
NS_IMETHOD SetPopupElement(nsIDOMElement* aPopupElement); \
NS_IMETHOD GetTooltipElement(nsIDOMElement** aTooltipElement); \
NS_IMETHOD SetTooltipElement(nsIDOMElement* aTooltipElement); \
NS_IMETHOD GetFocus(nsIDOMXULFocusTracker** aFocus); \
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn); \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn); \
@ -58,8 +63,10 @@ public:
#define NS_FORWARD_IDOMXULDOCUMENT(_to) \
NS_IMETHOD GetPopup(nsIDOMElement** aPopup) { return _to GetPopup(aPopup); } \
NS_IMETHOD SetPopup(nsIDOMElement* aPopup) { return _to SetPopup(aPopup); } \
NS_IMETHOD GetPopupElement(nsIDOMElement** aPopupElement) { return _to GetPopupElement(aPopupElement); } \
NS_IMETHOD SetPopupElement(nsIDOMElement* aPopupElement) { return _to SetPopupElement(aPopupElement); } \
NS_IMETHOD GetTooltipElement(nsIDOMElement** aTooltipElement) { return _to GetTooltipElement(aTooltipElement); } \
NS_IMETHOD SetTooltipElement(nsIDOMElement* aTooltipElement) { return _to SetTooltipElement(aTooltipElement); } \
NS_IMETHOD GetFocus(nsIDOMXULFocusTracker** aFocus) { return _to GetFocus(aFocus); } \
NS_IMETHOD GetElementById(const nsString& aId, nsIDOMElement** aReturn) { return _to GetElementById(aId, aReturn); } \
NS_IMETHOD GetElementsByAttribute(const nsString& aName, const nsString& aValue, nsIDOMNodeList** aReturn) { return _to GetElementsByAttribute(aName, aValue, aReturn); } \

View File

@ -50,8 +50,12 @@ NS_DEF_PTR(nsIDOMNodeList);
// XULDocument property ids
//
enum XULDocument_slots {
XULDOCUMENT_POPUP = -1,
XULDOCUMENT_FOCUS = -2
XULDOCUMENT_POPUPELEMENT = -1,
XULDOCUMENT_TOOLTIPELEMENT = -2,
XULDOCUMENT_FOCUS = -3
};
/***********************************************************************/
@ -61,30 +65,88 @@ enum XULDocument_slots {
PR_STATIC_CALLBACK(JSBool)
GetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULDocument *a = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *a = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx);
nsIScriptSecurityManager *secMan;
PRBool ok;
PRBool ok = PR_FALSE;
if (NS_OK != scriptCX->GetSecurityManager(&secMan)) {
return JS_FALSE;
}
switch(JSVAL_TO_INT(id)) {
case XULDOCUMENT_POPUP:
case XULDOCUMENT_POPUPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popup", &ok);
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popupelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (NS_OK == a->GetPopup(&prop)) {
if (NS_OK == a->GetPopupElement(&prop)) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, vp);
}
else {
return JS_FALSE;
}
break;
}
case XULDOCUMENT_TOOLTIPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.tooltipelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (NS_OK == a->GetTooltipElement(&prop)) {
// get the js object
nsJSUtils::nsConvertObjectToJSVal((nsISupports *)prop, cx, vp);
}
@ -129,36 +191,102 @@ GetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
PR_STATIC_CALLBACK(JSBool)
SetXULDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
nsIDOMXULDocument *a = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *a = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
// If there's no private data, this must be the prototype, so ignore
if (nsnull == a) {
return JS_TRUE;
}
if (JSVAL_IS_INT(id)) {
nsIScriptContext *scriptCX = (nsIScriptContext *)JS_GetContextPrivate(cx);
nsIScriptSecurityManager *secMan;
PRBool ok;
PRBool ok = PR_FALSE;
if (NS_OK != scriptCX->GetSecurityManager(&secMan)) {
return JS_FALSE;
}
switch(JSVAL_TO_INT(id)) {
case XULDOCUMENT_POPUP:
case XULDOCUMENT_POPUPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popup", &ok);
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.popupelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIElementIID, "Element",
cx, *vp)) {
return JS_FALSE;
}
a->SetPopup(prop);
a->SetPopupElement(prop);
NS_IF_RELEASE(prop);
break;
}
case XULDOCUMENT_TOOLTIPELEMENT:
{
secMan->CheckScriptAccess(scriptCX, obj, "xuldocument.tooltipelement", &ok);
if (!ok) {
//Need to throw error here
return JS_FALSE;
}
nsIDOMElement* prop;
if (PR_FALSE == nsJSUtils::nsConvertJSValToObject((nsISupports **)&prop,
kIElementIID, "Element",
cx, *vp)) {
return JS_FALSE;
}
a->SetTooltipElement(prop);
NS_IF_RELEASE(prop);
break;
}
@ -211,7 +339,8 @@ ResolveXULDocument(JSContext *cx, JSObject *obj, jsval id)
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMElement* nativeRet;
nsAutoString b0;
@ -263,7 +392,8 @@ XULDocumentGetElementById(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
PR_STATIC_CALLBACK(JSBool)
XULDocumentGetElementsByAttribute(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)JS_GetPrivate(cx, obj);
nsIDOMXULDocument *nativeThis = (nsIDOMXULDocument*)nsJSUtils::nsGetNativeThis(cx, obj);
JSBool rBool = JS_FALSE;
nsIDOMNodeList* nativeRet;
nsAutoString b0;
@ -335,7 +465,10 @@ JSClass XULDocumentClass = {
//
static JSPropertySpec XULDocumentProperties[] =
{
{"popup", XULDOCUMENT_POPUP, JSPROP_ENUMERATE},
{"popupElement", XULDOCUMENT_POPUPELEMENT, JSPROP_ENUMERATE},
{"tooltipElement", XULDOCUMENT_TOOLTIPELEMENT, JSPROP_ENUMERATE},
{"focus", XULDOCUMENT_FOCUS, JSPROP_ENUMERATE | JSPROP_READONLY},
{0}
};

View File

@ -782,10 +782,20 @@ protected:
nsString mCommand;
nsCOMPtr<nsIRDFResource> mFragmentRoot; // [OWNER]
nsVoidArray mSubDocuments; // [OWNER] of subelements
nsCOMPtr<nsIDOMElement> mPopup; // [OWNER] of this popup element in the doc
PRBool mIsPopup;
nsCOMPtr<nsIDOMHTMLFormElement> mHiddenForm; // [OWNER] of this content element
nsCOMPtr<nsIDOMXULFocusTracker> mFocusTracker; // [OWNER] of the focus tracker
// The following are pointers into the content model which provide access to
// the objects triggering either a popup or a tooltip. These are marked as
// [OWNER] only because someone could, through DOM calls, delete the object from the
// content model while the popup/tooltip was visible. If we didn't have a reference
// to it, the object would go away and we'd be left pointing to garbage. This
// does not introduce cycles into the ownership model because this is still
// parent/child ownership. Just wanted the reader to know hyatt and I had thought about
// this (pinkerton).
nsCOMPtr<nsIDOMElement> mPopupElement; // [OWNER] element triggering the popup
nsCOMPtr<nsIDOMElement> mTooltipElement; // [OWNER] element triggering the tooltip
};
PRInt32 XULDocumentImpl::gRefCnt = 0;
@ -2902,20 +2912,37 @@ XULDocumentImpl::CreateRange(nsIDOMRange** aRange)
// nsIDOMXULDocument interface
NS_IMETHODIMP
XULDocumentImpl::GetPopup(nsIDOMElement** anElement)
XULDocumentImpl::GetPopupElement(nsIDOMElement** anElement)
{
*anElement = mPopup;
*anElement = mPopupElement;
NS_IF_ADDREF(*anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::SetPopup(nsIDOMElement* anElement)
XULDocumentImpl::SetPopupElement(nsIDOMElement* anElement)
{
mPopup = dont_QueryInterface(anElement);
mPopupElement = dont_QueryInterface(anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::GetTooltipElement(nsIDOMElement** anElement)
{
*anElement = mTooltipElement;
NS_IF_ADDREF(*anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::SetTooltipElement(nsIDOMElement* anElement)
{
mTooltipElement = dont_QueryInterface(anElement);
return NS_OK;
}
NS_IMETHODIMP
XULDocumentImpl::GetFocus(nsIDOMXULFocusTracker** aTracker)
{
@ -3128,7 +3155,7 @@ XULDocumentImpl::CreatePopupDocument(nsIContent* aPopupElement, nsIDocument** aR
popupDoc->mNameSpaceManager = mNameSpaceManager;
// We share the mPopup
popupDoc->mPopup = mPopup;
popupDoc->mPopupElement = mPopupElement;
// Suck all of the root's content into our document.
// We need to make the XUL builder instantiate this node.

View File

@ -34,6 +34,8 @@
#include "nsIDocument.h"
#include "nsIContent.h"
#include "nsIDOMUIEvent.h"
#include "nsITimer.h"
////////////////////////////////////////////////////////////////////////
@ -41,10 +43,6 @@ static NS_DEFINE_IID(kXULPopupListenerCID, NS_XULPOPUPLISTENER_CID);
static NS_DEFINE_IID(kIXULPopupListenerIID, NS_IXULPOPUPLISTENER_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIDomNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDomElementIID, NS_IDOMELEMENT_IID);
static NS_DEFINE_IID(kIDomEventListenerIID, NS_IDOMEVENTLISTENER_IID);
////////////////////////////////////////////////////////////////////////
// PopupListenerImpl
//
@ -71,8 +69,8 @@ public:
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; };
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) ;
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) ;
// nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent) { return NS_OK; };
@ -82,16 +80,35 @@ public:
virtual nsresult HandleEvent(nsIDOMEvent* anEvent) { return NS_OK; };
protected:
virtual nsresult LaunchPopup(nsIDOMEvent* anEvent);
virtual nsresult LaunchPopup( nsIDOMElement* aElement, PRInt32 aScreenX, PRInt32 aScreenY,
PRInt32 aClientX, PRInt32 aClientY ) ;
nsresult FindDocumentForNode ( nsIDOMNode* inNode, nsIDOMXULDocument** outDoc ) ;
private:
nsIDOMElement* element; // Weak reference. The element will go away first.
// |mElement| is the node to which this listener is attached.
nsIDOMElement* mElement; // Weak ref. The element will go away first.
XULPopupType popupType;
nsCOMPtr<nsIDOMWindow> mPopup; // The popup. We are responsible for making it go away.
// The following members are not used unless |popupType| is tooltip.
// a timer for determining if a tooltip should be displayed.
static void sTooltipCallback ( nsITimer *aTimer, void *aClosure ) ;
nsCOMPtr<nsITimer> mTooltipTimer;
PRInt32 mMouseLocX, mMouseLocY; // mouse coordinates for tooltip event
// 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.
nsIDOMNode* mPossibleTooltipNode; // weak ref.
};
////////////////////////////////////////////////////////////////////////
XULPopupListenerImpl::XULPopupListenerImpl(void)
: mElement(nsnull), mPossibleTooltipNode(nsnull), mMouseLocX(0), mMouseLocY(0)
{
NS_INIT_REFCNT();
@ -99,6 +116,11 @@ XULPopupListenerImpl::XULPopupListenerImpl(void)
XULPopupListenerImpl::~XULPopupListenerImpl(void)
{
//XXX do we need to close the popup here? Will we get the right events as
//XXX the topLevel window is going away when the closebox is pressed?
if ( mPopup )
mPopup->Close();
}
NS_IMPL_ADDREF(XULPopupListenerImpl)
@ -126,7 +148,7 @@ XULPopupListenerImpl::QueryInterface(REFNSIID iid, void** result)
NS_ADDREF_THIS();
return NS_OK;
}
else if (iid.Equals(kIDomEventListenerIID)) {
else if (iid.Equals(nsIDOMEventListener::GetIID())) {
*result = (nsIDOMEventListener*)(nsIDOMMouseListener*)this;
NS_ADDREF_THIS();
return NS_OK;
@ -138,7 +160,7 @@ XULPopupListenerImpl::QueryInterface(REFNSIID iid, void** result)
NS_IMETHODIMP
XULPopupListenerImpl::Init(nsIDOMElement* aElement, const XULPopupType& popup)
{
element = aElement; // Weak reference. Don't addref it.
mElement = aElement; // Weak reference. Don't addref it.
popupType = popup;
return NS_OK;
}
@ -187,24 +209,186 @@ XULPopupListenerImpl::MouseDown(nsIDOMEvent* aMouseEvent)
return NS_OK;
}
//
// MouseOver
//
// If we're a tooltip, fire off a timer to see if a tooltip should be shown.
//
nsresult
XULPopupListenerImpl::LaunchPopup(nsIDOMEvent* anEvent)
XULPopupListenerImpl::MouseOver(nsIDOMEvent* aMouseEvent)
{
nsresult rv = NS_OK;
// make sure we're a tooltip. if not, bail.
if ( popupType != eXULPopupType_tooltip )
return NS_OK;
//XXX recognize when a popup is already up and immediately show the
//XXX tooltip for the new item if the dom element is different than
//XXX the element for which we are currently displaying the tip.
//XXX
//XXX for now, just be stupid to get things working.
// Kill off an old timer and create a new one.
if ( mTooltipTimer ) {
mTooltipTimer->Cancel();
mTooltipTimer = nsnull;
}
NS_NewTimer ( getter_AddRefs(mTooltipTimer) );
if ( mTooltipTimer ) {
nsCOMPtr<nsIDOMUIEvent> uiEvent ( do_QueryInterface(aMouseEvent) );
if ( uiEvent ) {
// stash the coordinates of the event so that we can still get back to it from within the
// timer scallback. Also stash the node that started this so we can put it into the
// document later on (if the timer ever fires).
nsCOMPtr<nsIDOMNode> eventTarget;
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
mPossibleTooltipNode = eventTarget.get();
// BUG: 8598, widget and mouse coords not set for MouseOver events.
// uiEvent->GetScreenX(&mMouseLocX);
// uiEvent->GetScreenY(&mMouseLocY);
mMouseLocX = 50; mMouseLocY = 50; // XXX until bug 8598 fixed
mTooltipTimer->Init(sTooltipCallback, this, 1000); // one second delay
}
}
else
NS_WARNING ( "Could not create a timer for tooltip tracking" );
return NS_OK;
} // MouseOver
//
// 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;
if ( mTooltipTimer )
mTooltipTimer->Cancel();
if ( mPopup ) {
mPopup->Close(); // hide the popup
mPopup = nsnull; // release the popup
// clear out the tooltip node on the document
nsCOMPtr<nsIDOMNode> eventTarget;
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
nsCOMPtr<nsIDOMXULDocument> doc;
FindDocumentForNode ( eventTarget, getter_AddRefs(doc) );
if ( doc )
doc->SetTooltipElement(nsnull);
}
return NS_OK;
} // MouseOut
//
// 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 (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
NS_ERROR("Unable to retrieve the document.");
return rv;
}
// Turn the document into a XUL document so we can use getElementById
nsCOMPtr<nsIDOMXULDocument> xulDocument = do_QueryInterface(document);
if (xulDocument == nsnull) {
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
//
nsresult
XULPopupListenerImpl::LaunchPopup ( nsIDOMEvent* anEvent )
{
// Retrieve our x and y position.
nsCOMPtr<nsIDOMUIEvent> uiEvent ( do_QueryInterface(anEvent) );
if (!uiEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
PRInt32 xPos, yPos;
uiEvent->GetScreenX(&xPos);
uiEvent->GetScreenY(&yPos);
PRInt32 offsetX, offsetY;
uiEvent->GetClientX(&offsetX);
uiEvent->GetClientY(&offsetY);
return LaunchPopup ( mElement, xPos, yPos, offsetX, offsetY );
}
//
// LaunchPopup
//
// Given the element on which the event was triggered and the mouse locations in
// screen and widget coordinates, popup a new window showing the appropriate
// 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
// the popup content in the document.
//
nsresult
XULPopupListenerImpl::LaunchPopup( nsIDOMElement* aElement, PRInt32 aScreenX, PRInt32 aScreenY,
PRInt32 aOffsetX, PRInt32 aOffsetY )
{
nsresult rv = NS_OK;
nsAutoString type("popup");
if (eXULPopupType_context == popupType)
if ( popupType == eXULPopupType_context )
type = "context";
else if ( popupType == eXULPopupType_tooltip )
type = "tooltip";
nsAutoString identifier;
element->GetAttribute(type, identifier);
mElement->GetAttribute(type, identifier);
if (identifier == "")
return rv;
// Try to find the popup content.
// 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.
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
if (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
NS_ERROR("Unable to retrieve the document.");
return rv;
@ -219,17 +403,15 @@ XULPopupListenerImpl::LaunchPopup(nsIDOMEvent* anEvent)
// XXX Handle the _child case for popups and context menus!
// Use getElementById to obtain the popup content.
// Use getElementById to obtain the popup content and gracefully fail if
// we didn't find any popup content in the document.
nsCOMPtr<nsIDOMElement> popupContent;
if (NS_FAILED(rv = xulDocument->GetElementById(identifier, getter_AddRefs(popupContent)))) {
NS_ERROR("GetElementById had some kind of spasm.");
return rv;
}
if (popupContent == nsnull) {
// Gracefully fail in this case.
if ( !popupContent )
return NS_OK;
}
// We have some popup content. Obtain our window.
nsIScriptContextOwner* owner = document->GetScriptContextOwner();
@ -242,42 +424,30 @@ XULPopupListenerImpl::LaunchPopup(nsIDOMEvent* anEvent)
if (domWindow != nsnull) {
// Find out if we're anchored.
nsAutoString anchorAlignment("none");
element->GetAttribute("popupanchor", anchorAlignment);
mElement->GetAttribute("popupanchor", anchorAlignment);
nsAutoString popupAlignment("topleft");
element->GetAttribute("popupalign", popupAlignment);
mElement->GetAttribute("popupalign", popupAlignment);
// Set the popup in the document for the duration of this call.
xulDocument->SetPopup(element);
// Set the popup in the document for the duration of this call.
xulDocument->SetPopupElement(mElement);
// Retrieve our x and y position.
nsCOMPtr<nsIDOMUIEvent>uiEvent;
uiEvent = do_QueryInterface(anEvent);
if (!uiEvent) {
//non-ui event passed in. bad things.
return NS_OK;
}
PRInt32 xPos, yPos;
uiEvent->GetScreenX(&xPos);
uiEvent->GetScreenY(&yPos);
// If we're anchored, we pass in client/screen offsets so that
// we can translate the frames corners to screen coords.
// we can translate the frames corners to screen coords.
PRInt32 xPos = aScreenX, yPos = aScreenY;
if (anchorAlignment != "none") {
PRInt32 offsetX, offsetY;
uiEvent->GetClientX(&offsetX);
uiEvent->GetClientY(&offsetY);
xPos = xPos-offsetX;
yPos = yPos-offsetY;
xPos -= aOffsetX;
yPos -= aOffsetY;
}
domWindow->CreatePopup(element, popupContent,
xPos, yPos,
type, anchorAlignment, popupAlignment);
domWindow->CreatePopup(mElement, popupContent,
xPos, yPos,
type, anchorAlignment, popupAlignment,
getter_AddRefs(mPopup));
if ( popupType == eXULPopupType_popup && mPopup )
mPopup->Focus();
// XXX For menus only, clear the document.popup field.
}
}
NS_RELEASE(global);
}
}
@ -290,10 +460,12 @@ nsresult
XULPopupListenerImpl::Blur(nsIDOMEvent* aMouseEvent)
{
nsresult rv = NS_OK;
#if 0
// ONLY NEEDED BECAUSE HYATT WAS LAZY
// Try to find the popup content.
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
if (NS_FAILED(rv = content->GetDocument(*getter_AddRefs(document)))) {
NS_ERROR("Unable to retrieve the document.");
return rv;
@ -319,7 +491,20 @@ XULPopupListenerImpl::Blur(nsIDOMEvent* aMouseEvent)
domWindow->Close();
}
}
#endif
// Blur events don't bubble, so this means our window lost focus.
// Let's check just to make sure.
nsCOMPtr<nsIDOMNode> eventTarget;
aMouseEvent->GetTarget(getter_AddRefs(eventTarget));
// Close, but only if we are the same target.
nsCOMPtr<nsIDOMNode> windowNode = do_QueryInterface(mPopup);
if (windowNode.get() == eventTarget.get()) {
mPopup->Close();
mPopup = nsnull;
}
// XXX Figure out how to fire the DESTROY event for the
// arbitrary XUL case
@ -329,6 +514,40 @@ XULPopupListenerImpl::Blur(nsIDOMEvent* aMouseEvent)
return rv;
}
//
// 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 |aClosure| object passed to
// us by the timer:
// -- the x/y coordinates of the mouse
// -- the dom node the user hovered over
//
void
XULPopupListenerImpl :: sTooltipCallback (nsITimer *aTimer, void *aClosure)
{
XULPopupListenerImpl* self = NS_STATIC_CAST(XULPopupListenerImpl*, aClosure);
if ( self ) {
// set the node in the document that triggered the tooltip and show it
nsCOMPtr<nsIDOMXULDocument> doc;
self->FindDocumentForNode ( self->mPossibleTooltipNode, getter_AddRefs(doc) );
if ( doc ) {
nsCOMPtr<nsIDOMElement> element ( do_QueryInterface(self->mPossibleTooltipNode) );
if ( element ) {
doc->SetTooltipElement ( element );
self->LaunchPopup ( element, self->mMouseLocX, self->mMouseLocY, 0, 0 );
}
} // if document
} // if "self" data valid
} // sTimerCallback
////////////////////////////////////////////////////////////////
nsresult
NS_NewXULPopupListener(nsIXULPopupListener** pop)

View File

@ -111,7 +111,7 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow) = 0;
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup) = 0;
/**
* Notify the WebShellContainer that a contained webshell is

View File

@ -266,7 +266,7 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow);
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup);
NS_IMETHOD FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult);
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken);
@ -2198,12 +2198,12 @@ nsWebShell::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent,
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow)
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup)
{
if (nsnull != mContainer) {
return mContainer->CreatePopup(aElement, aPopupContent, aXPos, aYPos, aPopupType,
anAnchorAlignment, aPopupAlignment,
aWindow);
aWindow, outPopup);
}
return NS_OK;
}

View File

@ -1807,7 +1807,7 @@ nsBrowserWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupConte
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow)
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup)
{
return NS_OK;
}

View File

@ -137,7 +137,7 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow);
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup);
NS_IMETHOD FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult);
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken);

View File

@ -575,7 +575,7 @@ nsXPBaseWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupConten
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow)
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup)
{
return NS_OK;
}

View File

@ -118,7 +118,7 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow);
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup);
NS_IMETHOD FindWebShellWithName(const PRUnichar* aName, nsIWebShell*& aResult);
NS_IMETHOD FocusAvailable(nsIWebShell* aFocusedWebShell, PRBool& aFocusTaken);

View File

@ -1004,9 +1004,17 @@ nsWebShellWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupCont
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow)
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup)
{
nsresult rv = NS_OK;
// clear out result param up front. It's an error if a legal place to
// stick the result isn't provided.
if ( !outPopup ) {
NS_ERROR ( "Invalid param -- need to provide a place for result" );
return NS_ERROR_INVALID_ARG;
}
*outPopup = nsnull;
nsCOMPtr<nsIContentViewerContainer> contentViewerContainer;
contentViewerContainer = do_QueryInterface(mWebShell);
@ -1082,6 +1090,8 @@ nsWebShellWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupCont
}
nsCOMPtr<nsIContent> popupContent = do_QueryInterface(aPopupContent);
if ( !popupContent )
return NS_OK; // It's ok. Really.
// Fire the CONSTRUCT DOM event to give JS/C++ a chance to build the popup
// dynamically.
@ -1090,7 +1100,7 @@ nsWebShellWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupCont
event.eventStructType = NS_EVENT;
event.message = NS_POPUP_CONSTRUCT;
rv = popupContent->HandleDOMEvent(*presContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
if (rv != NS_OK)
if ( NS_FAILED(rv) )
return rv;
// Find out if we're a menu.
@ -1103,10 +1113,9 @@ nsWebShellWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupCont
if (NS_FAILED(popupContent->ChildAt(0, *getter_AddRefs(rootContent))))
return NS_OK; // Doesn't matter. Don't report it.
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(rootContent);
nsString tagName;
if (NS_FAILED(rootElement->GetTagName(tagName)))
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(rootContent);
if ( !rootElement || NS_FAILED(rootElement->GetTagName(tagName)))
return NS_OK; // It's ok. Really.
if (tagName == "menu") {
@ -1223,16 +1232,18 @@ nsWebShellWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupCont
// (8) Set up the opener property
domWindow->SetOpener(aWindow);
// (9) Show the window, and give the window the focus.
// (9) Show the window. Don't give the focus yet because we may not want to.
// For example, popup windows want focus, but tooltips do not.
newWindow->Show(PR_TRUE);
domWindow->Focus();
// (10) Do some layout.
nsCOMPtr<nsIXULChildDocument> popupChild = do_QueryInterface(popupDocument);
popupChild->LayoutPopupDocument();
// XXX Do we return the popup document? Might want to, since it's kind of like
// a sick and twisted distortion of a window.open call.
// return the popup.
*outPopup = domWindow;
NS_ADDREF(*outPopup);
return rv;
}

View File

@ -88,7 +88,7 @@ public:
PRInt32 aXPos, PRInt32 aYPos,
const nsString& aPopupType, const nsString& anAnchorAlignment,
const nsString& aPopupAlignment,
nsIDOMWindow* aWindow);
nsIDOMWindow* aWindow, nsIDOMWindow** outPopup);
NS_IMETHOD ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode);