diff --git a/content/xul/content/src/nsXULPopupListener.cpp b/content/xul/content/src/nsXULPopupListener.cpp index 553c1f36e0d..51da831edf9 100644 --- a/content/xul/content/src/nsXULPopupListener.cpp +++ b/content/xul/content/src/nsXULPopupListener.cpp @@ -33,6 +33,7 @@ #include "nsIDOMMouseMotionListener.h" #include "nsRDFCID.h" +#include "nsIDOMXULPopupElement.h" #include "nsIScriptGlobalObject.h" #include "nsIDOMWindow.h" #include "nsIDOMXULDocument.h" @@ -486,11 +487,11 @@ XULPopupListenerImpl::LaunchPopup(PRInt32 aClientX, PRInt32 aClientY) mPopupContent = popupContent.get(); - nsCOMPtr uselessPopup; // XXX Should go away. - domWindow->CreatePopup(mElement, popupContent, + nsCOMPtr xulPopup = do_QueryInterface(popupContent); + if (xulPopup) + xulPopup->OpenPopup(mElement, xPos, yPos, - type, anchorAlignment, popupAlignment, - getter_AddRefs(uselessPopup)); + type, anchorAlignment, popupAlignment); } } } diff --git a/rdf/content/src/nsXULPopupElement.cpp b/rdf/content/src/nsXULPopupElement.cpp index 6ad46522977..c2733371d4a 100644 --- a/rdf/content/src/nsXULPopupElement.cpp +++ b/rdf/content/src/nsXULPopupElement.cpp @@ -38,6 +38,7 @@ #include "nsIServiceManager.h" #include "nsString.h" #include "nsIPopupSetFrame.h" +#include "nsIFrame.h" NS_IMPL_ADDREF_INHERITED(nsXULPopupElement, nsXULAggregateElement); NS_IMPL_RELEASE_INHERITED(nsXULPopupElement, nsXULAggregateElement); @@ -76,7 +77,6 @@ nsXULPopupElement::OpenPopup(nsIDOMElement* aElement, PRInt32 aXPos, PRInt32 aYP const nsString& aPopupType, const nsString& aAnchorAlignment, const nsString& aPopupAlignment) { - /* nsresult rv = NS_OK; nsCOMPtr content = do_QueryInterface(mOuter); @@ -109,13 +109,19 @@ nsXULPopupElement::OpenPopup(nsIDOMElement* aElement, PRInt32 aXPos, PRInt32 aYP if (!frame) return NS_OK; + // Obtain the element frame. + nsCOMPtr elementContent = do_QueryInterface(aElement); + nsIFrame* elementFrame; + presShell->GetPrimaryFrameFor(elementContent, &elementFrame); + if (!elementFrame) + return NS_OK; + // Pass this all off to the popup set frame. nsCOMPtr popupSetFrame = do_QueryInterface(frame); - nsCOMPtr popupContent = do_QueryInterface(aPopupContent); - popupSetFrame->CreatePopup(aElement, content, aXPos, aYPos, - aPopupType, anAnchorAlignment, + popupSetFrame->CreatePopup(elementFrame, content, aXPos, aYPos, + aPopupType, aAnchorAlignment, aPopupAlignment); - */ + return NS_OK; } @@ -123,7 +129,6 @@ nsXULPopupElement::OpenPopup(nsIDOMElement* aElement, PRInt32 aXPos, PRInt32 aYP NS_IMETHODIMP nsXULPopupElement::ClosePopup() { - /* // Close the popup by simulating proper dismissal. nsCOMPtr content = do_QueryInterface(mOuter); nsCOMPtr document; @@ -159,6 +164,6 @@ nsXULPopupElement::ClosePopup() nsCOMPtr popupSetFrame = do_QueryInterface(frame); popupSetFrame->DestroyPopup(); -*/ + return NS_OK; } diff --git a/rdf/content/src/nsXULPopupListener.cpp b/rdf/content/src/nsXULPopupListener.cpp index 553c1f36e0d..51da831edf9 100644 --- a/rdf/content/src/nsXULPopupListener.cpp +++ b/rdf/content/src/nsXULPopupListener.cpp @@ -33,6 +33,7 @@ #include "nsIDOMMouseMotionListener.h" #include "nsRDFCID.h" +#include "nsIDOMXULPopupElement.h" #include "nsIScriptGlobalObject.h" #include "nsIDOMWindow.h" #include "nsIDOMXULDocument.h" @@ -486,11 +487,11 @@ XULPopupListenerImpl::LaunchPopup(PRInt32 aClientX, PRInt32 aClientY) mPopupContent = popupContent.get(); - nsCOMPtr uselessPopup; // XXX Should go away. - domWindow->CreatePopup(mElement, popupContent, + nsCOMPtr xulPopup = do_QueryInterface(popupContent); + if (xulPopup) + xulPopup->OpenPopup(mElement, xPos, yPos, - type, anchorAlignment, popupAlignment, - getter_AddRefs(uselessPopup)); + type, anchorAlignment, popupAlignment); } } } diff --git a/xpfe/appshell/src/nsWebShellWindow.cpp b/xpfe/appshell/src/nsWebShellWindow.cpp index 26067383298..f880855c9a9 100644 --- a/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/xpfe/appshell/src/nsWebShellWindow.cpp @@ -1206,283 +1206,6 @@ nsWebShellWindow::GetPresShell(nsIPresShell** aPresShell) return NS_OK; } -NS_IMETHODIMP -nsWebShellWindow::CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, - PRInt32 aXPos, PRInt32 aYPos, - const nsString& aPopupType, const nsString& anAnchorAlignment, - const nsString& aPopupAlignment, - nsIDOMWindow* aWindow, nsIDOMWindow** outPopup) -{ - nsresult rv = NS_OK; - - // First we need to obtain the popup set frame that encapsulates the target popup. - // Without a popup set, we're dead in the water. - nsCOMPtr presShell; - if (NS_FAILED(GetPresShell(getter_AddRefs(presShell)))) { - return NS_OK; - } - - // Get the parent of the popup content. - nsCOMPtr popupSet; - aPopupContent->GetParentNode(getter_AddRefs(popupSet)); - if (!popupSet) - return NS_OK; - - // Do a sanity check to ensure we have a popup set element. - nsString tagName; - nsCOMPtr popupSetElement = do_QueryInterface(popupSet); - popupSetElement->GetTagName(tagName); - if (tagName != "popupset") - return NS_OK; - - // Now obtain the popup set frame. - nsCOMPtr popupSetContent = do_QueryInterface(popupSet); - nsIFrame* frame; - presShell->GetPrimaryFrameFor(popupSetContent, &frame); - if (!frame) - return NS_OK; - - // Retrieve the frame that corresponds to the element that the popup - // is attached to. - nsIFrame* elementFrame; - nsCOMPtr elementContent = do_QueryInterface(aElement); - presShell->GetPrimaryFrameFor(elementContent, &elementFrame); - if (!elementFrame) - return NS_OK; - - // Pass this all off to the popup set frame. - nsCOMPtr popupSetFrame = do_QueryInterface(frame); - nsCOMPtr popupContent = do_QueryInterface(aPopupContent); - popupSetFrame->CreatePopup(elementFrame, popupContent, aXPos, aYPos, - aPopupType, anAnchorAlignment, - aPopupAlignment); - - - /* - // 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 content = do_QueryInterface(aElement); - if (anAnchorAlignment != "none") { - // We need to compute our screen coordinates. - nsIFrame* primaryFrame; - presShell->GetPrimaryFrameFor(content, &primaryFrame); - if (primaryFrame) { - // Get the coordinates within the view. - nsRect rect; - nsIView * view; - nsPoint pnt; - primaryFrame->GetOffsetFromView(pnt, &view); - primaryFrame->GetRect(rect); - rect.x = pnt.x; - rect.y = pnt.y; - - float t2p; - presContext->GetTwipsToPixels(&t2p); - rect.x = NSToCoordRound((float)(rect.x)*t2p); - rect.y = NSToCoordRound((float)(rect.y)*t2p); - rect.width = NSToCoordRound((float)(rect.width)*t2p); - rect.height = NSToCoordRound((float)(rect.height)*t2p); - - if (anAnchorAlignment == "topleft") { - aXPos = rect.x + aXPos; - aYPos = rect.y + aYPos; - } - else if (anAnchorAlignment == "topright") { - aXPos = rect.x + rect.width + aXPos; - aYPos = rect.y + aYPos; - } - else if (anAnchorAlignment == "bottomleft") { - aXPos = rect.x + aXPos; - aYPos = rect.y + rect.height + aYPos; - } - else { - aXPos = rect.x + rect.width + aXPos; - aYPos = rect.y + rect.height + aYPos; - } - } - } - - nsCOMPtr popupContent = do_QueryInterface(aPopupContent); - if ( !popupContent ) - return NS_OK; // It's ok. Really. - - // Fire the create DOM event to give JS/C++ a chance to build the popup - // dynamically. After we fire off the event, make sure we check the result - // for |nsEventStatus_eConsumeNoDefault| which translates into an event - // handler returning false. If that happens, abort creating the popup. - nsEventStatus status = nsEventStatus_eIgnore; - nsMouseEvent event; - event.eventStructType = NS_EVENT; - event.message = NS_MENU_CREATE; - rv = popupContent->HandleDOMEvent(*presContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); - if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault ) - return rv; - - // Find out if we're a menu. - PRInt32 childCount; - popupContent->ChildCount(childCount); - if (childCount == 0) - return NS_OK; - - nsCOMPtr rootContent; - if (NS_FAILED(popupContent->ChildAt(0, *getter_AddRefs(rootContent)))) - return NS_OK; // Doesn't matter. Don't report it. - - nsString tagName; - nsCOMPtr rootElement = do_QueryInterface(rootContent); - if ( !rootElement || NS_FAILED(rootElement->GetTagName(tagName))) - return NS_OK; // It's ok. Really. - - if (tagName == "menu") { - - // XXX Need to distinguish between popup menus and context menus? - DoContextMenu(nsnull, rootElement, mWindow, aXPos, aYPos, aPopupAlignment, anAnchorAlignment); - - // Fire the destroy DOM event to give JS/C++ a chance to destroy the popup contents - status = nsEventStatus_eIgnore; - event.eventStructType = NS_EVENT; - event.message = NS_MENU_DESTROY; - rv = popupContent->HandleDOMEvent(*presContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); - return rv; - } - - if (tagName != "window") - return NS_OK; // I promise. It really is ok. Stop whining. - - // Handle the arbitrary popup XUL case. - - // (1) Create a top-level chromeless window. The size of the window can be specified - // on the window tag contained inside. Retrieve the webshell from the new nsWebShellWindow. - - nsCOMPtr newWindow; - - nsWebShellWindow* window = new nsWebShellWindow(); - if (nsnull == window) { - return NS_ERROR_OUT_OF_MEMORY; - } - nsWidgetInitData widgetInitData; - widgetInitData.mWindowType = eWindowType_popup; - widgetInitData.mBorderStyle = eBorderStyle_default; - - window->SetIntrinsicallySized(PR_TRUE); - rv = window->Initialize((nsIWebShellWindow *) nsnull, nsnull, nsnull, - PR_TRUE, PR_TRUE, nsnull, nsnull, - 1, 1, widgetInitData); - - if (NS_FAILED(rv)) - return rv; - - newWindow = window; - - // Move the window to aXPos and aYPos - nsCOMPtr browserWindow = do_QueryInterface(newWindow); - browserWindow->MoveTo(aXPos, aYPos); - - // (2) Get the webshell - nsCOMPtr newShell; - newWindow->GetWebShell(*getter_AddRefs(newShell)); - - nsCOMPtr domWindow; - if (NS_FAILED(rv = ConvertWebShellToDOMWindow(newShell, getter_AddRefs(domWindow)))) { - NS_ERROR("Unable to retrieve the DOM window from the new web shell."); - return rv; - } - - // (3) We need to create a new document that clones the original document's popup - // content. This new document must use the different root and a different global script - // context (window object) but everything else about it is the same (namespaces, URLs, - // stylesheets). - nsCOMPtr document; - content->GetDocument(*getter_AddRefs(document)); - if (document == nsnull) - return NS_ERROR_FAILURE; - nsCOMPtr parentDocument = do_QueryInterface(document); - if (parentDocument == nsnull) - return NS_ERROR_FAILURE; - - nsCOMPtr popupDocument; - if (NS_FAILED(rv = parentDocument->CreatePopupDocument(rootContent, getter_AddRefs(popupDocument)))) { - NS_ERROR("Unable to create the child popup document."); - return rv; - } - - // The tricky part now is bypassing the normal load process and just putting a document into - // the webshell. This is particularly nasty, since webshells don't normally even know - // about their documents - // (4) Create a document viewer - nsCOMPtr documentViewer; - nsCOMPtr docFactory; - if (NS_FAILED(rv = nsComponentManager::CreateInstance(kLayoutDocumentLoaderFactoryCID, nsnull, - kIDocumentLoaderFactoryIID, - (void**)getter_AddRefs(docFactory)))) { - NS_ERROR("Unable to instantiate layout's doc loader factory."); - return rv; - } - nsCOMPtr cvContainer = do_QueryInterface(newShell); - if (NS_FAILED(rv = docFactory->CreateInstanceForDocument(cvContainer, - popupDocument, - "view", - getter_AddRefs(documentViewer)))) { - NS_ERROR("I couldn't get a document viewer for the popup document."); - return rv; - } - - // (5) Feed the webshell to the content viewer - documentViewer->SetContainer(cvContainer); - - // (6) Tell the content viewer container to embed the content viewer. - // (This step causes everything to be set up for an initial flow.) - if (NS_FAILED(rv = cvContainer->Embed(documentViewer, "view", nsnull))) { - NS_ERROR("Unable to embed the viewer in the container."); - return rv; - } - - // (7) Hook up a blur handler to the window that will cause it to close. - nsCOMPtr popupListener; - if (NS_FAILED(rv = nsComponentManager::CreateInstance(kXULPopupListenerCID, - nsnull, - kIXULPopupListenerIID, - (void**) getter_AddRefs(popupListener)))) { - NS_ERROR("Unable to create an instance of the popup listener object."); - return rv; - } - nsIContent* popupRoot = popupDocument->GetRootContent(); - nsCOMPtr popupRootElement = do_QueryInterface(popupRoot); - if (NS_FAILED(rv = popupListener->Init(popupRootElement, eXULPopupType_blur))) { - NS_ERROR("Unable to initialize our blur listener."); - return rv; - } - NS_IF_RELEASE(popupRoot); - nsCOMPtr blurListener = do_QueryInterface(popupListener); - nsCOMPtr targetWindow = do_QueryInterface(domWindow); - targetWindow->AddEventListener("blur", blurListener, PR_FALSE); - - // (8) Set up the opener property - domWindow->SetOpener(aWindow); - - // (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); - - // (10) Do some layout. - nsCOMPtr popupChild = do_QueryInterface(popupDocument); - popupChild->LayoutPopupDocument(); - - // return the popup. - *outPopup = domWindow; - NS_ADDREF(*outPopup); - */ - - return rv; -} - NS_IMETHODIMP nsWebShellWindow::ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode) { diff --git a/xpfe/appshell/src/nsWebShellWindow.h b/xpfe/appshell/src/nsWebShellWindow.h index 60eb87e45a5..cdab5479be3 100644 --- a/xpfe/appshell/src/nsWebShellWindow.h +++ b/xpfe/appshell/src/nsWebShellWindow.h @@ -95,13 +95,6 @@ public: const PRUnichar* aURL, nsresult aStatus); - - NS_IMETHOD CreatePopup(nsIDOMElement* aElement, nsIDOMElement* aPopupContent, - PRInt32 aXPos, PRInt32 aYPos, - const nsString& aPopupType, const nsString& anAnchorAlignment, - const nsString& aPopupAlignment, - nsIDOMWindow* aWindow, nsIDOMWindow** outPopup); - NS_IMETHOD ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode); NS_IMETHOD NewWebShell(PRUint32 aChromeMask,