зеркало из https://github.com/mozilla/pjs.git
Getting rid of createPopup
This commit is contained in:
Родитель
519b52041d
Коммит
91dc71fa50
|
@ -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<nsIDOMWindow> uselessPopup; // XXX Should go away.
|
||||
domWindow->CreatePopup(mElement, popupContent,
|
||||
nsCOMPtr<nsIDOMXULPopupElement> xulPopup = do_QueryInterface(popupContent);
|
||||
if (xulPopup)
|
||||
xulPopup->OpenPopup(mElement,
|
||||
xPos, yPos,
|
||||
type, anchorAlignment, popupAlignment,
|
||||
getter_AddRefs(uselessPopup));
|
||||
type, anchorAlignment, popupAlignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<nsIContent> 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<nsIContent> 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<nsIPopupSetFrame> popupSetFrame = do_QueryInterface(frame);
|
||||
nsCOMPtr<nsIContent> 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<nsIContent> content = do_QueryInterface(mOuter);
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
|
@ -159,6 +164,6 @@ nsXULPopupElement::ClosePopup()
|
|||
|
||||
nsCOMPtr<nsIPopupSetFrame> popupSetFrame = do_QueryInterface(frame);
|
||||
popupSetFrame->DestroyPopup();
|
||||
*/
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -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<nsIDOMWindow> uselessPopup; // XXX Should go away.
|
||||
domWindow->CreatePopup(mElement, popupContent,
|
||||
nsCOMPtr<nsIDOMXULPopupElement> xulPopup = do_QueryInterface(popupContent);
|
||||
if (xulPopup)
|
||||
xulPopup->OpenPopup(mElement,
|
||||
xPos, yPos,
|
||||
type, anchorAlignment, popupAlignment,
|
||||
getter_AddRefs(uselessPopup));
|
||||
type, anchorAlignment, popupAlignment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<nsIPresShell> presShell;
|
||||
if (NS_FAILED(GetPresShell(getter_AddRefs(presShell)))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the parent of the popup content.
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMElement> popupSetElement = do_QueryInterface(popupSet);
|
||||
popupSetElement->GetTagName(tagName);
|
||||
if (tagName != "popupset")
|
||||
return NS_OK;
|
||||
|
||||
// Now obtain the popup set frame.
|
||||
nsCOMPtr<nsIContent> 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<nsIContent> elementContent = do_QueryInterface(aElement);
|
||||
presShell->GetPrimaryFrameFor(elementContent, &elementFrame);
|
||||
if (!elementFrame)
|
||||
return NS_OK;
|
||||
|
||||
// Pass this all off to the popup set frame.
|
||||
nsCOMPtr<nsIPopupSetFrame> popupSetFrame = do_QueryInterface(frame);
|
||||
nsCOMPtr<nsIContent> 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<nsIContent> 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<nsIContent> 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<nsIContent> rootContent;
|
||||
if (NS_FAILED(popupContent->ChildAt(0, *getter_AddRefs(rootContent))))
|
||||
return NS_OK; // Doesn't matter. Don't report it.
|
||||
|
||||
nsString tagName;
|
||||
nsCOMPtr<nsIDOMElement> 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<nsIWebShellWindow> 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<nsIBrowserWindow> browserWindow = do_QueryInterface(newWindow);
|
||||
browserWindow->MoveTo(aXPos, aYPos);
|
||||
|
||||
// (2) Get the webshell
|
||||
nsCOMPtr<nsIWebShell> newShell;
|
||||
newWindow->GetWebShell(*getter_AddRefs(newShell));
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> 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<nsIDocument> document;
|
||||
content->GetDocument(*getter_AddRefs(document));
|
||||
if (document == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIXULParentDocument> parentDocument = do_QueryInterface(document);
|
||||
if (parentDocument == nsnull)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDocument> 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<nsIContentViewer> documentViewer;
|
||||
nsCOMPtr<nsIDocumentLoaderFactory> 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<nsIContentViewerContainer> 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<nsIXULPopupListener> 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<nsIDOMElement> 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<nsIDOMFocusListener> blurListener = do_QueryInterface(popupListener);
|
||||
nsCOMPtr<nsIDOMEventTarget> 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<nsIXULChildDocument> popupChild = do_QueryInterface(popupDocument);
|
||||
popupChild->LayoutPopupDocument();
|
||||
|
||||
// return the popup.
|
||||
*outPopup = domWindow;
|
||||
NS_ADDREF(*outPopup);
|
||||
*/
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebShellWindow::ContentShellAdded(nsIWebShell* aChildShell, nsIContent* frameNode)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче