This commit is contained in:
hyatt%netscape.com 2000-01-28 03:04:40 +00:00
Родитель 519b52041d
Коммит 91dc71fa50
5 изменённых файлов: 22 добавлений и 299 удалений

Просмотреть файл

@ -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,