Mozilla/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp
danm%netscape.com 686bfccd17 reinstate recently removed disabling of modal window's parent. bug 19221. r:hyatt
git-svn-id: svn://10.0.0.236/trunk@60807 18797224-902f-48f8-a5cc-f745e15eee43
2000-02-15 05:06:08 +00:00

2239 lines
70 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#include "nsWebShellWindow.h"
#include "nsLayoutCID.h"
#include "nsIWeakReference.h"
#include "nsIDocumentLoader.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsIIOService.h"
#include "nsIURL.h"
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
#include "nsIPref.h"
#include "nsINameSpaceManager.h"
#include "nsEscape.h"
#include "nsVoidArray.h"
#include "nsIScriptGlobalObject.h"
#include "nsIDOMWindow.h"
#include "nsPIDOMWindow.h"
#include "nsIDOMEventTarget.h"
#include "nsIDOMFocusListener.h"
#include "nsIXULPopupListener.h"
#include "nsIDOMXULElement.h"
#include "nsRDFCID.h"
#include "nsGUIEvent.h"
#include "nsWidgetsCID.h"
#include "nsIWidget.h"
#include "nsIAppShell.h"
#include "nsIXULWindowCallbacks.h"
#include "nsIAppShellService.h"
#include "nsAppShellCIDs.h"
#include "nsXULCommand.h"
#include "nsIDOMCharacterData.h"
#include "nsIDOMNodeList.h"
#include "nsIMenuBar.h"
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsIContextMenu.h"
// For JS Execution
#include "nsIScriptGlobalObjectOwner.h"
#include "nsIJSContextStack.h"
#include "nsIEventQueueService.h"
#include "plevent.h"
#include "prmem.h"
#include "nsIDOMXULDocument.h"
#include "nsIDOMXULCommandDispatcher.h"
#include "nsIDocumentViewer.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIDocumentLoader.h"
#include "nsIDocumentLoaderFactory.h"
#include "nsIObserverService.h"
#include "prprf.h"
//#include "nsIDOMHTMLInputElement.h"
//#include "nsIDOMHTMLImageElement.h"
#include "nsIContent.h" // for menus
// For calculating size
#include "nsIFrame.h"
#include "nsIPresShell.h"
#include "nsIPresContext.h"
#include "nsIBaseWindow.h"
#include "nsIDocShellTreeItem.h"
#include "nsIMarkupDocumentViewer.h"
// HACK for M4, should be removed by M5
#ifdef XP_MAC
#include <Menus.h>
#endif
#include "nsIMenuItem.h"
#include "nsIDOMXULDocument.h"
// End hack
#include "nsIWindowMediator.h"
#include "nsIPopupSetFrame.h"
/* Define Class IDs */
static NS_DEFINE_CID(kWindowCID, NS_WINDOW_CID);
static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID);
static NS_DEFINE_CID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID);
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuBarCID, NS_MENUBAR_CID);
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
static NS_DEFINE_CID(kContextMenuCID, NS_CONTEXTMENU_CID);
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
static NS_DEFINE_CID(kLayoutDocumentLoaderFactoryCID, NS_LAYOUT_DOCUMENT_LOADER_FACTORY_CID);
static NS_DEFINE_CID(kXULPopupListenerCID, NS_XULPOPUPLISTENER_CID);
#ifdef DEBUG_rods
#define DEBUG_MENUSDEL 1
#endif
#include "nsICommonDialogs.h"
static NS_DEFINE_CID( kCommonDialogsCID, NS_CommonDialog_CID );
#include "nsIWalletService.h"
static NS_DEFINE_CID(kWalletServiceCID, NS_WALLETSERVICE_CID);
#include "nsIWebShell.h"
const char * kPrimaryContentTypeValue = "content-primary";
struct ThreadedWindowEvent {
PLEvent event;
nsWebShellWindow *window;
};
// The web shell info object is used to hold information about content areas that will
// subsequently be filled in when we receive a webshell added notification.
struct nsWebShellInfo {
nsString id; // The identifier of the iframe or frame node in the XUL tree.
PRBool primary; // whether it's considered a/the primary content
nsIWebShell* child; // The child web shell that will end up being used for the content area.
nsWebShellInfo(const nsString& anID, PRBool aPrimary, nsIWebShell* aChildShell)
{
id = anID;
primary = aPrimary;
child = aChildShell;
NS_IF_ADDREF(aChildShell);
}
~nsWebShellInfo()
{
NS_IF_RELEASE(child);
}
};
// a little utility object to push an event queue and pop it when it
// goes out of scope. should probably be in a file of utility functions.
class stEventQueueStack {
public:
stEventQueueStack();
~stEventQueueStack();
nsresult Success() const { return mPushedStack; }
private:
nsIEventQueueService *mService;
nsIEventQueue *mQueue;
nsresult mGotService,
mPushedStack;
};
stEventQueueStack::stEventQueueStack() {
// ick! this makes bad assumptions about the structure of the service, but
// the service manager seems to need to work this way...
mGotService = nsServiceManager::GetService(kEventQueueServiceCID,
NS_GET_IID(nsIEventQueueService),
(nsISupports **) &mService);
mPushedStack = mGotService;
if (NS_SUCCEEDED(mGotService))
mService->PushThreadEventQueue(&mQueue);
}
stEventQueueStack::~stEventQueueStack() {
if (NS_SUCCEEDED(mPushedStack))
mService->PopThreadEventQueue(mQueue);
// more ick!
if (NS_SUCCEEDED(mGotService))
nsServiceManager::ReleaseService(kEventQueueServiceCID,
NS_STATIC_CAST(nsISupports *, mService));
}
nsWebShellWindow::nsWebShellWindow() : nsXULWindow()
{
NS_INIT_REFCNT();
mWebShell = nsnull;
mWindow = nsnull;
mCallbacks = nsnull;
mLockedUntilChromeLoad = PR_FALSE;
mIntrinsicallySized = PR_FALSE;
mDebuting = PR_FALSE;
mLoadDefaultPage = PR_TRUE;
}
nsWebShellWindow::~nsWebShellWindow()
{
if (nsnull != mWebShell) {
nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(mWebShell));
shellAsWin->Destroy();
NS_RELEASE(mWebShell);
}
mWindow = nsnull; // Force release here.
NS_IF_RELEASE(mCallbacks);
}
NS_IMPL_ADDREF(nsWebShellWindow);
NS_IMPL_RELEASE(nsWebShellWindow);
NS_INTERFACE_MAP_BEGIN(nsWebShellWindow)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebShellContainer)
NS_INTERFACE_MAP_ENTRY(nsIWebShellWindow)
NS_INTERFACE_MAP_ENTRY(nsIWebShellContainer)
NS_INTERFACE_MAP_ENTRY(nsIDocumentLoaderObserver)
NS_INTERFACE_MAP_ENTRY(nsIBrowserWindow)
NS_INTERFACE_MAP_ENTRY(nsIPrompt)
NS_INTERFACE_MAP_ENTRY(nsINetPrompt)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIXULWindow)
NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_END
nsresult nsWebShellWindow::Initialize(nsIWebShellWindow* aParent,
nsIAppShell* aShell, nsIURI* aUrl,
PRBool aCreatedVisible,
PRBool aLoadDefaultPage,
nsIXULWindowCallbacks *aCallbacks,
PRInt32 aInitialWidth, PRInt32 aInitialHeight,
nsWidgetInitData& widgetInitData)
{
nsresult rv;
nsCOMPtr<nsIWidget> parentWidget;
mShowAfterLoad = aCreatedVisible;
mLoadDefaultPage = aLoadDefaultPage;
// XXX: need to get the default window size from prefs...
// Doesn't come from prefs... will come from CSS/XUL/RDF
nsRect r(0, 0, aInitialWidth, aInitialHeight);
// Create top level window
rv = nsComponentManager::CreateInstance(kWindowCID, nsnull, NS_GET_IID(nsIWidget),
(void**)&mWindow);
if (NS_OK != rv) {
return rv;
}
/* This next bit is troublesome. We carry two different versions of a pointer
to our parent window. One is the parent window's widget, which is passed
to our own widget. The other is a weak reference we keep here to our
parent WebShellWindow. The former is useful to the widget, and we can't
trust its treatment of the parent reference because they're platform-
specific. The latter is useful to this class.
A better implementation would be one in which the parent keeps strong
references to its children and closes them before it allows itself
to be closed. This would mimic the behaviour of OSes that support
top-level child windows in OSes that do not. Later.
*/
if (aParent) {
aParent->GetWidget(*getter_AddRefs(parentWidget));
mParentWindow = getter_AddRefs(NS_GetWeakReference(aParent));
}
mWindow->SetClientData(this);
mWindow->Create((nsIWidget *)parentWidget, // Parent nsIWidget
r, // Widget dimensions
nsWebShellWindow::HandleEvent, // Event handler function
nsnull, // Device context
aShell, // Application shell
nsnull, // nsIToolkit
&widgetInitData); // Widget initialization data
mWindow->GetClientBounds(r);
mWindow->SetBackgroundColor(NS_RGB(192,192,192));
// Create web shell
rv = nsComponentManager::CreateInstance(kWebShellCID, nsnull,
NS_GET_IID(nsIWebShell),
(void**)&mWebShell);
if (NS_OK != rv) {
return rv;
}
mDocShell = do_QueryInterface(mWebShell);
r.x = r.y = 0;
rv = mWebShell->Init(mWindow->GetNativeData(NS_NATIVE_WIDGET),
r.x, r.y, r.width, r.height,
nsScrollPreference_kNeverScroll,
PR_TRUE, // Allow Plugins
PR_TRUE);
mWebShell->SetContainer(this);
mWebShell->SetDocLoaderObserver(this);
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
NS_ENSURE_SUCCESS(EnsureChromeTreeOwner(), NS_ERROR_FAILURE);
docShellAsItem->SetTreeOwner(mChromeTreeOwner);
docShellAsItem->SetItemType(nsIDocShellTreeItem::typeChrome);
/*
* XXX: How should preferences be supplied to the nsWebShellWindow?
* Should there be the notion of a global preferences service?
* Or should there be many preferences components based on
* the user profile...
*/
// Initialize the webshell with the preferences service
nsIPref *prefs;
rv = nsServiceManager::GetService(kPrefCID,
NS_GET_IID(nsIPref),
(nsISupports **)&prefs);
if (NS_SUCCEEDED(rv)) {
// Set the prefs in the outermost webshell.
mWebShell->SetPrefs(prefs);
nsServiceManager::ReleaseService(kPrefCID, prefs);
}
NS_IF_RELEASE(mCallbacks);
mCallbacks = aCallbacks;
NS_IF_ADDREF(mCallbacks);
if (nsnull != aUrl) {
char *tmpStr = NULL;
nsAutoString urlString;
rv = aUrl->GetSpec(&tmpStr);
if (NS_FAILED(rv)) return rv;
urlString = tmpStr;
nsCRT::free(tmpStr);
rv = mWebShell->LoadURL(urlString.GetUnicode());
}
return rv;
}
/*
* Close the window
*/
NS_METHOD
nsWebShellWindow::Close()
{
#ifdef XP_MAC // Anyone still using native menus should add themselves here.
// unregister as document listener
// this is needed for menus
nsCOMPtr<nsIContentViewer> cv;
if(mDocShell)
mDocShell->GetContentViewer(getter_AddRefs(cv));
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if(docv)
{
nsCOMPtr<nsIDocument> doc;
docv->GetDocument(*getter_AddRefs(doc));
if(doc)
doc->RemoveObserver(NS_STATIC_CAST(nsIDocumentObserver*, this));
}
#endif
return nsXULWindow::Destroy();
}
/*
* Event handler function...
*
* This function is called to process events for the nsIWidget of the
* nsWebShellWindow...
*/
nsEventStatus PR_CALLBACK
nsWebShellWindow::HandleEvent(nsGUIEvent *aEvent)
{
nsEventStatus result = nsEventStatus_eIgnore;
nsIWebShell* webShell = nsnull;
// Get the WebShell instance...
if (nsnull != aEvent->widget) {
void* data;
aEvent->widget->GetClientData(data);
if (nsnull != data) {
webShell = ((nsWebShellWindow*)data)->mWebShell;
}
}
if (nsnull != webShell) {
switch(aEvent->message) {
/*
* For size events, the WebShell must be resized to fill the entire
* client area of the window...
*/
case NS_MOVE: {
void* data;
nsWebShellWindow *win;
aEvent->widget->GetClientData(data);
win = NS_REINTERPRET_CAST(nsWebShellWindow *, data);
win->StoreBoundsToXUL(PR_TRUE, PR_FALSE);
break;
}
case NS_SIZE: {
void* data;
nsWebShellWindow *win;
nsSizeEvent* sizeEvent = (nsSizeEvent*)aEvent;
nsCOMPtr<nsIBaseWindow> shellAsWin(do_QueryInterface(webShell));
shellAsWin->SetPositionAndSize(0, 0, sizeEvent->windowSize->width,
sizeEvent->windowSize->height, PR_FALSE);
aEvent->widget->GetClientData(data);
win = NS_REINTERPRET_CAST(nsWebShellWindow *, data);
win->StoreBoundsToXUL(PR_FALSE, PR_TRUE);
result = nsEventStatus_eConsumeNoDefault;
break;
}
case NS_XUL_CLOSE: {
void* data;
nsWebShellWindow *win;
aEvent->widget->GetClientData(data);
win = NS_REINTERPRET_CAST(nsWebShellWindow *, data);
if (!win->ExecuteCloseHandler())
win->Close();
break;
}
/*
* Notify the ApplicationShellService that the window is being closed...
*/
case NS_DESTROY: {
void* data;
aEvent->widget->GetClientData(data);
if (data)
((nsWebShellWindow *)data)->Close();
break;
}
case NS_ACTIVATE: {
printf("nsWebShellWindow::NS_ACTIVATE\n");
break;
}
case NS_DEACTIVATE: {
printf("nsWebShellWindow::NS_DEACTIVATE\n");
void* data;
aEvent->widget->GetClientData(data);
if (!data)
break;
nsCOMPtr<nsIDOMWindow> domWindow;
nsCOMPtr<nsIWebShell> contentShell;
((nsWebShellWindow *)data)->GetContentWebShell(getter_AddRefs(contentShell));
if (contentShell) {
if (NS_SUCCEEDED(((nsWebShellWindow *)data)->
ConvertWebShellToDOMWindow(contentShell, getter_AddRefs(domWindow)))) {
if(domWindow){
nsCOMPtr<nsPIDOMWindow> privateDOMWindow = do_QueryInterface(domWindow);
if(privateDOMWindow)
privateDOMWindow->Deactivate();
}
}
}
else if (domWindow) {
nsCOMPtr<nsPIDOMWindow> privateDOMWindow = do_QueryInterface(domWindow);
if(privateDOMWindow)
privateDOMWindow->Deactivate();
}
break;
}
case NS_GOTFOCUS: {
printf("nsWebShellWindow::GOTFOCUS\n");
void* data;
aEvent->widget->GetClientData(data);
if (!data)
break;
nsCOMPtr<nsIDOMDocument> domDocument;
nsCOMPtr<nsIDOMWindow> domWindow;
((nsWebShellWindow *)data)->ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow));
domWindow->GetDocument(getter_AddRefs(domDocument));
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(domDocument);
if (xulDoc) {
nsCOMPtr<nsIDOMXULCommandDispatcher> commandDispatcher;
xulDoc->GetCommandDispatcher(getter_AddRefs(commandDispatcher));
if (commandDispatcher) {
nsCOMPtr<nsIDOMWindow> focusedWindow;
commandDispatcher->GetFocusedWindow(getter_AddRefs(focusedWindow));
if (focusedWindow) {
commandDispatcher->SetSuppressFocus(PR_TRUE);
domWindow->Focus(); // This sets focus, but we'll ignore it.
// A subsequent activate will cause us to stop suppressing.
break;
}
}
}
nsCOMPtr<nsIWebShell> contentShell;
((nsWebShellWindow *)data)->GetContentWebShell(getter_AddRefs(contentShell));
if (contentShell) {
if (NS_SUCCEEDED(((nsWebShellWindow *)data)->
ConvertWebShellToDOMWindow(contentShell, getter_AddRefs(domWindow)))) {
domWindow->Focus();
}
}
else if (domWindow)
domWindow->Focus();
break;
}
default:
break;
}
}
return nsEventStatus_eIgnore;
}
NS_IMETHODIMP
nsWebShellWindow::WillLoadURL(nsIWebShell* aShell, const PRUnichar* aURL,
nsLoadType aReason)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::BeginLoadURL(nsIWebShell* aShell, const PRUnichar* aURL)
{
// If loading a new root .xul document, then redo chrome.
if (aShell == mWebShell) {
mChromeLoaded = PR_FALSE;
}
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::ProgressLoadURL(nsIWebShell* aShell, const PRUnichar* aURL,
PRInt32 aProgress, PRInt32 aProgressMax)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::EndLoadURL(nsIWebShell* aWebShell, const PRUnichar* aURL,
nsresult aStatus)
{
return NS_OK;
}
//----------------------------------------
NS_IMETHODIMP nsWebShellWindow::CreateMenu(nsIMenuBar * aMenuBar,
nsIDOMNode * aMenuNode,
nsString & aMenuName)
{
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, NS_GET_IID(nsIMenu), (void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
aMenuBar->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsMenu->Create(supports, aMenuName);
NS_RELEASE(supports);
// Set nsMenu Name
pnsMenu->SetLabel(aMenuName);
// Make nsMenu a child of nsMenuBar
aMenuBar->AddMenu(pnsMenu);
// Open the node so that the contents are visible.
nsCOMPtr<nsIDOMElement> menuElement = do_QueryInterface(aMenuNode);
if (menuElement)
menuElement->SetAttribute("open", "true");
// Begin menuitem inner loop
// Now get the kids. Retrieve our menupopup child.
nsCOMPtr<nsIDOMNode> menuPopupNode;
aMenuNode->GetFirstChild(getter_AddRefs(menuPopupNode));
while (menuPopupNode) {
nsCOMPtr<nsIDOMElement> menuPopupElement(do_QueryInterface(menuPopupNode));
if (menuPopupElement) {
nsString menuPopupNodeType;
menuPopupElement->GetNodeName(menuPopupNodeType);
if (menuPopupNodeType.Equals("menupopup"))
break;
}
nsCOMPtr<nsIDOMNode> oldMenuPopupNode(menuPopupNode);
oldMenuPopupNode->GetNextSibling(getter_AddRefs(menuPopupNode));
}
if (!menuPopupNode)
return NS_OK;
nsCOMPtr<nsIDOMNode> menuitemNode;
menuPopupNode->GetFirstChild(getter_AddRefs(menuitemNode));
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
nsString menuitemName;
menuitemElement->GetNodeName(menuitemNodeType);
if (menuitemNodeType.Equals("menuitem")) {
// LoadMenuItem
LoadMenuItem(pnsMenu, menuitemElement, menuitemNode);
} else if (menuitemNodeType.Equals("menuseparator")) {
pnsMenu->AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Load a submenu
LoadSubMenu(pnsMenu, menuitemElement, menuitemNode);
}
}
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
// The parent owns us, so we can release
NS_RELEASE(pnsMenu);
}
return NS_OK;
}
//----------------------------------------
NS_IMETHODIMP nsWebShellWindow::LoadMenuItem(
nsIMenu * pParentMenu,
nsIDOMElement * menuitemElement,
nsIDOMNode * menuitemNode)
{
nsString menuitemName;
nsString menuitemCmd;
menuitemElement->GetAttribute(nsAutoString("value"), menuitemName);
menuitemElement->GetAttribute(nsAutoString("cmd"), menuitemCmd);
// Create nsMenuItem
nsIMenuItem * pnsMenuItem = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuItemCID, nsnull, NS_GET_IID(nsIMenuItem), (void**)&pnsMenuItem);
if (NS_OK == rv) {
// Create MenuDelegate - this is the intermediator inbetween
// the DOM node and the nsIMenuItem
// The nsWebShellWindow wacthes for Document changes and then notifies the
// the appropriate nsMenuDelegate object
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(menuitemNode));
if (!domElement) {
return NS_ERROR_FAILURE;
}
pnsMenuItem->Create(pParentMenu, menuitemName, 0);
// Set nsMenuItem Name
//pnsMenuItem->SetLabel(menuitemName);
// Set key shortcut and modifiers
nsAutoString keyAtom("key");
nsString keyValue;
domElement->GetAttribute(keyAtom, keyValue);
// Try to find the key node.
nsCOMPtr<nsIDocument> document;
nsCOMPtr<nsIContent> content = do_QueryInterface(domElement);
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("not XUL!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMElement> keyElement;
xulDocument->GetElementById(keyValue, getter_AddRefs(keyElement));
if(keyElement){
PRUint8 modifiers = knsMenuItemNoModifier;
nsAutoString shiftAtom("shift");
nsAutoString altAtom("alt");
nsAutoString commandAtom("command");
nsString shiftValue;
nsString altValue;
nsString commandValue;
nsString keyChar = " ";
keyElement->GetAttribute(keyAtom, keyChar);
keyElement->GetAttribute(shiftAtom, shiftValue);
keyElement->GetAttribute(altAtom, altValue);
keyElement->GetAttribute(commandAtom, commandValue);
if(keyChar != " ")
pnsMenuItem->SetShortcutChar(keyChar);
if(shiftValue == "true")
modifiers |= knsMenuItemShiftModifier;
if(altValue == "true")
modifiers |= knsMenuItemAltModifier;
if(commandValue == "false")
modifiers |= knsMenuItemCommandModifier;
pnsMenuItem->SetModifiers(modifiers);
}
// Make nsMenuItem a child of nsMenu
nsISupports * supports = nsnull;
pnsMenuItem->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports);
NS_RELEASE(supports);
nsAutoString cmdAtom("onaction");
nsString cmdName;
domElement->GetAttribute(cmdAtom, cmdName);
nsXULCommand * menuDelegate = new nsXULCommand();
if ( menuDelegate ) {
menuDelegate->SetCommand(cmdName);
menuDelegate->SetWebShell(mWebShell);
menuDelegate->SetDOMElement(domElement);
menuDelegate->SetMenuItem(pnsMenuItem);
} else {
NS_RELEASE( pnsMenuItem );
return NS_ERROR_OUT_OF_MEMORY;
}
nsIXULCommand * icmd;
if (NS_OK == menuDelegate->QueryInterface(NS_GET_IID(nsIXULCommand), (void**) &icmd)) {
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menuDelegate));
if (listener)
{
pnsMenuItem->AddMenuListener(listener);
#ifdef DEBUG_MENUSDEL
printf("Adding menu listener to [%s]\n", menuitemName.ToNewCString());
#endif
}
#ifdef DEBUG_MENUSDEL
else
{
printf("*** NOT Adding menu listener to [%s]\n", menuitemName.ToNewCString());
}
#endif
NS_RELEASE(icmd);
}
// The parent owns us, so we can release
NS_RELEASE(pnsMenuItem);
}
return NS_OK;
}
//----------------------------------------
void nsWebShellWindow::LoadSubMenu(
nsIMenu * pParentMenu,
nsIDOMElement * menuElement,
nsIDOMNode * menuNode)
{
nsString menuName;
menuElement->GetAttribute(nsAutoString("value"), menuName);
//printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
// Create nsMenu
nsIMenu * pnsMenu = nsnull;
nsresult rv = nsComponentManager::CreateInstance(kMenuCID, nsnull, NS_GET_IID(nsIMenu), (void**)&pnsMenu);
if (NS_OK == rv) {
// Call Create
nsISupports * supports = nsnull;
pParentMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsMenu->Create(supports, menuName);
NS_RELEASE(supports); // Balance QI
// Open the node so that the contents are visible.
menuElement->SetAttribute("open", "true");
// Set nsMenu Name
pnsMenu->SetLabel(menuName);
// Make nsMenu a child of parent nsMenu
//pParentMenu->AddMenu(pnsMenu);
supports = nsnull;
pnsMenu->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pParentMenu->AddItem(supports);
NS_RELEASE(supports);
// Begin menuitem inner loop
// Now get the kids. Retrieve our menupopup child.
nsCOMPtr<nsIDOMNode> menuPopupNode;
menuNode->GetFirstChild(getter_AddRefs(menuPopupNode));
while (menuPopupNode) {
nsCOMPtr<nsIDOMElement> menuPopupElement(do_QueryInterface(menuPopupNode));
if (menuPopupElement) {
nsString menuPopupNodeType;
menuPopupElement->GetNodeName(menuPopupNodeType);
if (menuPopupNodeType.Equals("menupopup"))
break;
}
nsCOMPtr<nsIDOMNode> oldMenuPopupNode(menuPopupNode);
oldMenuPopupNode->GetNextSibling(getter_AddRefs(menuPopupNode));
}
if (!menuPopupNode)
return;
nsCOMPtr<nsIDOMNode> menuitemNode;
menuPopupNode->GetFirstChild(getter_AddRefs(menuitemNode));
while (menuitemNode) {
nsCOMPtr<nsIDOMElement> menuitemElement(do_QueryInterface(menuitemNode));
if (menuitemElement) {
nsString menuitemNodeType;
menuitemElement->GetNodeName(menuitemNodeType);
#ifdef DEBUG_saari
printf("Type [%s] %d\n", menuitemNodeType.ToNewCString(), menuitemNodeType.Equals("menuseparator"));
#endif
if (menuitemNodeType.Equals("menuitem")) {
// Load a menuitem
LoadMenuItem(pnsMenu, menuitemElement, menuitemNode);
} else if (menuitemNodeType.Equals("menuseparator")) {
pnsMenu->AddSeparator();
} else if (menuitemNodeType.Equals("menu")) {
// Add a submenu
LoadSubMenu(pnsMenu, menuitemElement, menuitemNode);
}
}
nsCOMPtr<nsIDOMNode> oldmenuitemNode(menuitemNode);
oldmenuitemNode->GetNextSibling(getter_AddRefs(menuitemNode));
} // end menu item innner loop
// The parent owns us, so we can release
NS_RELEASE(pnsMenu);
}
}
//----------------------------------------
void nsWebShellWindow::DynamicLoadMenus(nsIDOMDocument * aDOMDoc, nsIWidget * aParentWindow)
{
nsRect oldRect;
mWindow->GetClientBounds(oldRect);
// locate the window element which holds toolbars and menus and commands
nsCOMPtr<nsIDOMElement> element;
aDOMDoc->GetDocumentElement(getter_AddRefs(element));
if (!element) {
return;
}
nsCOMPtr<nsIDOMNode> window(do_QueryInterface(element));
nsresult rv;
int endCount = 0;
nsCOMPtr<nsIDOMNode> menubarNode(FindNamedDOMNode(nsAutoString("menubar"), window, endCount, 1));
if (menubarNode) {
nsIMenuBar * pnsMenuBar = nsnull;
rv = nsComponentManager::CreateInstance(kMenuBarCID, nsnull, NS_GET_IID(nsIMenuBar), (void**)&pnsMenuBar);
if (NS_OK == rv) {
if (nsnull != pnsMenuBar) {
// set pnsMenuBar as a nsMenuListener on aParentWindow
nsCOMPtr<nsIMenuListener> menuListener;
pnsMenuBar->QueryInterface(NS_GET_IID(nsIMenuListener), getter_AddRefs(menuListener));
//fake event
nsMenuEvent fake;
menuListener->MenuConstruct(fake, aParentWindow, menubarNode, mWebShell);
#ifdef XP_MAC
#else
// Resize around the menu.
rv = NS_ERROR_FAILURE;
// do a resize
nsCOMPtr<nsIContentViewer> contentViewer;
if( NS_FAILED(mWebShell->GetContentViewer(getter_AddRefs(contentViewer))))
{
NS_WARN_IF_FALSE(PR_FALSE, "Error Getting contentViewer");
return;
}
nsCOMPtr<nsIDocumentViewer> docViewer;
docViewer = do_QueryInterface(contentViewer);
if (!docViewer) {
NS_ERROR("Document viewer interface not supported by the content viewer.");
return;
}
nsCOMPtr<nsIPresContext> presContext;
if (NS_FAILED(rv = docViewer->GetPresContext(*getter_AddRefs(presContext)))) {
NS_ERROR("Unable to retrieve the doc viewer's presentation context.");
return;
}
nsCOMPtr<nsIPresShell> presShell;
if (NS_FAILED(rv = presContext->GetShell(getter_AddRefs(presShell)))) {
NS_ERROR("Unable to retrieve the shell from the presentation context.");
return;
}
nsRect rect;
if (NS_FAILED(rv = mWindow->GetClientBounds(rect))) {
NS_ERROR("Failed to get web shells bounds");
return;
}
// Resize the browser window by the difference.
PRInt32 heightDelta = oldRect.height - rect.height;
nsRect currentBounds;
GetWindowBounds(currentBounds);
SizeWindowTo(currentBounds.width, currentBounds.height + heightDelta,
PR_FALSE, PR_FALSE);
// END REFLOW CODE
#endif
} // end if ( nsnull != pnsMenuBar )
}
} // end if (menuBar)
} // nsWebShellWindow::DynamicLoadMenus
//----------------------------------------
void nsWebShellWindow::LoadMenus(nsIDOMDocument * aDOMDoc, nsIWidget * aParentWindow)
{
// locate the window element which holds toolbars and menus and commands
nsCOMPtr<nsIDOMElement> element;
aDOMDoc->GetDocumentElement(getter_AddRefs(element));
if (!element) {
return;
}
nsCOMPtr<nsIDOMNode> window(do_QueryInterface(element));
nsresult rv;
int endCount = 0;
nsCOMPtr<nsIDOMNode> menubarNode(FindNamedDOMNode(nsAutoString("menubar"), window, endCount, 1));
if (menubarNode) {
nsIMenuBar * pnsMenuBar = nsnull;
rv = nsComponentManager::CreateInstance(kMenuBarCID, nsnull, NS_GET_IID(nsIMenuBar), (void**)&pnsMenuBar);
if (NS_OK == rv) {
if (nsnull != pnsMenuBar) {
pnsMenuBar->Create(aParentWindow);
// set pnsMenuBar as a nsMenuListener on aParentWindow
nsCOMPtr<nsIMenuListener> menuListener;
pnsMenuBar->QueryInterface(NS_GET_IID(nsIMenuListener), getter_AddRefs(menuListener));
aParentWindow->AddMenuListener(menuListener);
nsCOMPtr<nsIDOMNode> menuNode;
menubarNode->GetFirstChild(getter_AddRefs(menuNode));
while (menuNode) {
nsCOMPtr<nsIDOMElement> menuElement(do_QueryInterface(menuNode));
if (menuElement) {
nsString menuNodeType;
nsString menuName;
menuElement->GetNodeName(menuNodeType);
if (menuNodeType.Equals("menu")) {
menuElement->GetAttribute(nsAutoString("value"), menuName);
#ifdef DEBUG_rods
printf("Creating Menu [%s] \n", menuName.ToNewCString()); // this leaks
#endif
CreateMenu(pnsMenuBar, menuNode, menuName);
}
}
nsCOMPtr<nsIDOMNode> oldmenuNode(menuNode);
oldmenuNode->GetNextSibling(getter_AddRefs(menuNode));
} // end while (nsnull != menuNode)
// Give the aParentWindow this nsMenuBar to own.
aParentWindow->SetMenuBar(pnsMenuBar);
// HACK: force a paint for now
pnsMenuBar->Paint();
// HACK for M4, should be removed by M5
#ifdef XP_MAC
Handle tempMenuBar = ::GetMenuBar(); // Get a copy of the menu list
pnsMenuBar->SetNativeData((void*)tempMenuBar);
#endif
// The parent owns the menubar, so we can release it
NS_RELEASE(pnsMenuBar);
} // end if ( nsnull != pnsMenuBar )
}
} // end if (menuBar)
} // nsWebShellWindow::LoadMenus
//------------------------------------------------------------------------------
void nsWebShellWindow::DoContextMenu(
nsMenuEvent * aMenuEvent,
nsIDOMNode * aMenuNode,
nsIWidget * aParentWindow,
PRInt32 aX,
PRInt32 aY,
const nsString& aPopupAlignment,
const nsString& aAnchorAlignment)
{
if (aMenuNode) {
nsIContextMenu * pnsContextMenu;
nsresult rv = nsComponentManager::CreateInstance(kContextMenuCID, nsnull, NS_GET_IID(nsIContextMenu), (void**)&pnsContextMenu);
if (NS_SUCCEEDED(rv) && pnsContextMenu) {
nsISupports * supports;
aParentWindow->QueryInterface(NS_GET_IID(nsISupports), (void**) &supports);
pnsContextMenu->Create(supports, aPopupAlignment, aAnchorAlignment);
NS_RELEASE(supports);
pnsContextMenu->SetLocation(aX,aY);
// Set webshell
pnsContextMenu->SetWebShell( mWebShell );
// Set DOM node
pnsContextMenu->SetDOMNode( aMenuNode );
// Construct and show menu
nsIMenuListener * listener;
pnsContextMenu->QueryInterface(NS_GET_IID(nsIMenuListener), (void**) &listener);
// Dynamically construct and track the menu
listener->MenuSelected(*aMenuEvent);
// Destroy the menu
listener->MenuDeselected(*aMenuEvent);
// The parent owns the context menu, so we can release it
NS_RELEASE(listener);
NS_RELEASE(pnsContextMenu);
}
} // end if (aMenuNode)
}
//------------------------------------------------------------------------------
NS_IMETHODIMP
nsWebShellWindow::GetContentShellById(const nsString& aID, nsIWebShell** aChildShell)
{
// Set to null just to be certain
*aChildShell = nsnull;
nsCOMPtr<nsIDocShellTreeItem> content;
nsXULWindow::GetContentShellById(aID.GetUnicode(), getter_AddRefs(content));
if(!content)
return NS_ERROR_FAILURE;
CallQueryInterface(content, aChildShell);
return NS_OK;
}
//------------------------------------------------------------------------------
NS_IMETHODIMP
nsWebShellWindow::ConvertWebShellToDOMWindow(nsIWebShell* aShell, nsIDOMWindow** aDOMWindow)
{
nsCOMPtr<nsIScriptGlobalObjectOwner> globalObjectOwner(do_QueryInterface(aShell));
NS_ENSURE_TRUE(globalObjectOwner, NS_ERROR_FAILURE);
nsCOMPtr<nsIScriptGlobalObject> globalObject;
globalObjectOwner->GetScriptGlobalObject(getter_AddRefs(globalObject));
NS_ENSURE_TRUE(globalObject, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMWindow> newDOMWindow(do_QueryInterface(globalObject));
NS_ENSURE_TRUE(newDOMWindow, NS_ERROR_FAILURE);
*aDOMWindow = newDOMWindow.get();
NS_ADDREF(*aDOMWindow);
return NS_OK;
}
//----------------------------------------
// nsIWebShellWindow methods...
//----------------------------------------
NS_IMETHODIMP
nsWebShellWindow::Show(PRBool aShow)
{
return nsXULWindow::SetVisibility(aShow);
}
NS_IMETHODIMP
nsWebShellWindow::ShowModal()
{
nsresult rv;
nsCOMPtr<nsIWebShellWindow> parentWindow;
nsCOMPtr<nsIWidget> parentWidget;
parentWindow = do_QueryReferent(mParentWindow);
if (parentWindow)
parentWindow->GetWidget(*getter_AddRefs(parentWidget));
if (parentWidget)
parentWidget->Enable(PR_FALSE);
rv = nsXULWindow::ShowModal();
if (parentWidget) {
parentWidget->Enable(PR_TRUE);
parentWindow->Show(PR_TRUE); // bring to front
}
return rv;
}
// yes, this one's name and ShowModal are a confusing pair. plan is to merge
// the two someday.
NS_IMETHODIMP
nsWebShellWindow::ShowModally(PRBool aPrepare)
{
nsresult rv;
nsIEventQueue *eventQ;
nsCOMPtr<nsIWidget> parentWidget;
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
if (NS_FAILED(rv))
return rv;
eventQ = NULL;
if (aPrepare)
eventQService->PushThreadEventQueue(&eventQ);
parentWidget = do_QueryReferent(mParentWindow);
if (parentWidget)
parentWidget->Enable(PR_FALSE);
rv = ShowModal();
if (parentWidget)
parentWidget->Enable(PR_TRUE);
if (eventQ)
eventQService->PopThreadEventQueue(eventQ);
return rv;
}
/* return the main, outermost webshell in this window */
NS_IMETHODIMP
nsWebShellWindow::GetWebShell(nsIWebShell *& aWebShell)
{
aWebShell = mWebShell;
NS_ADDREF(mWebShell);
return NS_OK;
}
/* return the webshell intended to hold (html) content. In a simple
browser window, that would be the main content area. If no such
webshell was found for any reason, the outermost webshell will be
returned. (Note that is the main chrome webshell, and probably
not what you wanted, but at least it's a webshell.)
Also note that if no content webshell was marked "primary,"
we return the chrome webshell, even if (non-primary) content webshells
do exist. Thas was done intentionally. The selection would be
nondeterministic, and it seems dangerous to set a precedent like that.
*/
NS_IMETHODIMP
nsWebShellWindow::GetContentWebShell(nsIWebShell **aResult)
{
*aResult = nsnull;
nsCOMPtr<nsIDocShellTreeItem> content;
GetPrimaryContentShell(getter_AddRefs(content));
if(!content)
return NS_OK;
CallQueryInterface(content, aResult);
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::GetWidget(nsIWidget *& aWidget)
{
aWidget = mWindow;
NS_IF_ADDREF(aWidget);
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::GetDOMWindow(nsIDOMWindow** aDOMWindow)
{
return ConvertWebShellToDOMWindow(mWebShell, aDOMWindow);
}
void *
nsWebShellWindow::HandleModalDialogEvent(PLEvent *aEvent)
{
ThreadedWindowEvent *event = (ThreadedWindowEvent *) aEvent;
event->window->ShowModal();
return 0;
}
void
nsWebShellWindow::DestroyModalDialogEvent(PLEvent *aEvent)
{
PR_Free(aEvent);
}
//----------------------------------------
// nsIDocumentLoaderObserver implementation
//----------------------------------------
NS_IMETHODIMP
nsWebShellWindow::OnStartDocumentLoad(nsIDocumentLoader* loader,
nsIURI* aURL, const char* aCommand)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::OnEndDocumentLoad(nsIDocumentLoader* loader,
nsIChannel* channel, nsresult aStatus)
{
#ifdef DEBUG_MENUSDEL
printf("OnEndDocumentLoad\n");
#endif
/* We get notified every time a page/Frame is loaded. But we need to
* Load the menus, run the startup script etc.. only once. So, Use
* the mChrome Initialized member to check whether chrome should be
* initialized or not - Radha
*/
if (mChromeLoaded)
return NS_OK;
mChromeLoaded = PR_TRUE;
mLockedUntilChromeLoad = PR_FALSE;
#ifdef XP_MAC // Anyone still using native menus should add themselves here.
// register as document listener
// this is needed for menus
nsCOMPtr<nsIContentViewer> cv;
mWebShell->GetContentViewer(getter_AddRefs(cv));
if (cv) {
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if (!docv)
return NS_OK;
nsCOMPtr<nsIDocument> doc;
docv->GetDocument(*getter_AddRefs(doc));
if (!doc)
return NS_OK;
doc->AddObserver(NS_STATIC_CAST(nsIDocumentObserver*, this));
}
#endif
ExecuteStartupCode();
#ifdef XP_MAC // Anyone still using native menus should add themselves here.
///////////////////////////////
// Find the Menubar DOM and Load the menus, hooking them up to the loaded commands
///////////////////////////////
nsCOMPtr<nsIDOMDocument> menubarDOMDoc(GetNamedDOMDoc(nsAutoString("this"))); // XXX "this" is a small kludge for code reused
if (menubarDOMDoc)
{
#ifdef SOME_PLATFORM // Anyone using native non-dynamic menus should add themselves here.
LoadMenus(menubarDOMDoc, mWindow);
// Context Menu test
nsCOMPtr<nsIDOMElement> element;
menubarDOMDoc->GetDocumentElement(getter_AddRefs(element));
nsCOMPtr<nsIDOMNode> window(do_QueryInterface(element));
int endCount = 0;
contextMenuTest = FindNamedDOMNode(nsAutoString("contextmenu"), window, endCount, 1);
// End Context Menu test
#else
DynamicLoadMenus(menubarDOMDoc, mWindow);
#endif
}
#endif // XP_MAC
OnChromeLoaded();
LoadContentAreas();
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::OnStartURLLoad(nsIDocumentLoader* loader,
nsIChannel* channel)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::OnProgressURLLoad(nsIDocumentLoader* loader,
nsIChannel* channel,
PRUint32 aProgress,
PRUint32 aProgressMax)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::OnStatusURLLoad(nsIDocumentLoader* loader,
nsIChannel* channel, nsString& aMsg)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::OnEndURLLoad(nsIDocumentLoader* loader,
nsIChannel* channel, nsresult aStatus)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::HandleUnknownContentType(nsIDocumentLoader* loader,
nsIChannel* channel,
const char *aContentType,
const char *aCommand )
{
return NS_OK;
}
//----------------------------------------
nsCOMPtr<nsIDOMNode> nsWebShellWindow::FindNamedDOMNode(const nsString &aName, nsIDOMNode * aParent, PRInt32 & aCount, PRInt32 aEndCount)
{
if(!aParent)
return nsnull;
nsCOMPtr<nsIDOMNode> node;
aParent->GetFirstChild(getter_AddRefs(node));
while (node) {
nsString name;
node->GetNodeName(name);
//printf("FindNamedDOMNode[%s]==[%s] %d == %d\n", aName.ToNewCString(), name.ToNewCString(), aCount+1, aEndCount); //this leaks
if (name.Equals(aName)) {
aCount++;
if (aCount == aEndCount)
return node;
}
PRBool hasChildren;
node->HasChildNodes(&hasChildren);
if (hasChildren) {
nsCOMPtr<nsIDOMNode> found(FindNamedDOMNode(aName, node, aCount, aEndCount));
if (found)
return found;
}
nsCOMPtr<nsIDOMNode> oldNode = node;
oldNode->GetNextSibling(getter_AddRefs(node));
}
node = do_QueryInterface(nsnull);
return node;
} // nsWebShellWindow::FindNamedDOMNode
//----------------------------------------
nsCOMPtr<nsIDOMDocument> nsWebShellWindow::GetNamedDOMDoc(const nsString & aWebShellName)
{
nsCOMPtr<nsIDOMDocument> domDoc; // result == nsnull;
// first get the toolbar child WebShell
nsCOMPtr<nsIWebShell> childWebShell;
if (aWebShellName.Equals("this")) { // XXX small kludge for code reused
childWebShell = do_QueryInterface(mWebShell);
} else {
mWebShell->FindChildWithName(aWebShellName.GetUnicode(), *getter_AddRefs(childWebShell));
if (!childWebShell)
return domDoc;
}
nsCOMPtr<nsIContentViewer> cv;
childWebShell->GetContentViewer(getter_AddRefs(cv));
if (!cv)
return domDoc;
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if (!docv)
return domDoc;
nsCOMPtr<nsIDocument> doc;
docv->GetDocument(*getter_AddRefs(doc));
if (doc)
return nsCOMPtr<nsIDOMDocument>(do_QueryInterface(doc));
return domDoc;
} // nsWebShellWindow::GetNamedDOMDoc
//----------------------------------------
PRInt32 nsWebShellWindow::GetDocHeight(nsIDocument * aDoc)
{
nsIPresShell * presShell = aDoc->GetShellAt(0);
if (!presShell)
return 0;
nsCOMPtr<nsIPresContext> presContext;
presShell->GetPresContext(getter_AddRefs(presContext));
if (presContext) {
nsRect rect;
presContext->GetVisibleArea(rect);
nsIFrame * rootFrame;
nsSize size;
presShell->GetRootFrame(&rootFrame);
if (rootFrame) {
rootFrame->GetSize(size);
float t2p;
presContext->GetTwipsToPixels(&t2p);
printf("Doc size %d,%d\n", PRInt32((float)size.width*t2p),
PRInt32((float)size.height*t2p));
//return rect.height;
return PRInt32((float)rect.height*t2p);
//return PRInt32((float)size.height*presContext->GetTwipsToPixels());
}
}
NS_RELEASE(presShell);
return 0;
}
//----------------------------------------
/**
* Get nsIDOMNode corresponding to a given webshell
* @param aShell the given webshell
* @return the corresponding DOM element, null if for some reason there is none
*/
nsCOMPtr<nsIDOMNode>
nsWebShellWindow::GetDOMNodeFromWebShell(nsIWebShell *aShell)
{
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aShell));
nsCOMPtr<nsIDOMElement> element;
GetDOMElementFromDocShell(docShell, getter_AddRefs(element));
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(element));
return node;
}
/**
* XXX Hack for XUL Window callbacks. MUST GO AWAY!!!!
*/
void nsWebShellWindow::ExecuteStartupCode()
{
nsCOMPtr<nsIDOMNode> webshellNode = GetDOMNodeFromWebShell(mWebShell);
nsCOMPtr<nsIDOMElement> webshellElement;
if (webshellNode)
webshellElement = do_QueryInterface(webshellNode);
if (mCallbacks)
mCallbacks->ConstructBeforeJavaScript(mWebShell);
// Execute the string in the onLoad attribute of the webshellElement.
nsString startupCode;
if (mCallbacks)
mCallbacks->ConstructAfterJavaScript(mWebShell);
}
/* copy the window's size and position to the window tag */
void nsWebShellWindow::StoreBoundsToXUL(PRBool aPosition, PRBool aSize)
{
PersistPositionAndSize(aPosition, aSize);
} // StoreBoundsToXUL
void nsWebShellWindow::KillPersistentSize()
{
PRBool persistX, persistY;
GetPersistence(&persistX, &persistY, nsnull, nsnull);
SetPersistence(persistX, persistY, PR_FALSE, PR_FALSE);
}
// if the main document URL specified URLs for any content areas, start them loading
void nsWebShellWindow::LoadContentAreas() {
nsAutoString searchSpec;
// fetch the chrome document URL
nsCOMPtr<nsIContentViewer> contentViewer;
mWebShell->GetContentViewer(getter_AddRefs(contentViewer));
if (contentViewer) {
nsCOMPtr<nsIDocumentViewer> docViewer = do_QueryInterface(contentViewer);
if (docViewer) {
nsCOMPtr<nsIDocument> doc;
docViewer->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIURI> mainURL = getter_AddRefs(doc->GetDocumentURL());
if (mainURL) {
char *search = nsnull;
nsCOMPtr<nsIURL> url = do_QueryInterface(mainURL);
if (url)
url->GetQuery(&search);
searchSpec = search;
nsCRT::free(search);
}
}
}
// content URLs are specified in the search part of the URL
// as <contentareaID>=<escapedURL>[;(repeat)]
if (searchSpec.Length() > 0) {
PRInt32 begPos,
eqPos,
endPos;
nsString contentAreaID,
contentURL;
char *urlChar;
nsIWebShell *contentShell;
nsresult rv;
for (endPos = 0; endPos < searchSpec.Length(); ) {
// extract contentAreaID and URL substrings
begPos = endPos;
eqPos = searchSpec.FindChar('=', PR_FALSE,begPos);
if (eqPos < 0)
break;
endPos = searchSpec.FindChar(';', PR_FALSE,eqPos);
if (endPos < 0)
endPos = searchSpec.Length();
searchSpec.Mid(contentAreaID, begPos, eqPos-begPos);
searchSpec.Mid(contentURL, eqPos+1, endPos-eqPos-1);
endPos++;
// see if we have a webshell with a matching contentAreaID
rv = GetContentShellById(contentAreaID, &contentShell);
if (NS_SUCCEEDED(rv)) {
urlChar = contentURL.ToNewCString();
if (urlChar) {
nsUnescape(urlChar);
contentURL = urlChar;
contentShell->LoadURL(contentURL.GetUnicode());
delete [] urlChar;
}
NS_RELEASE(contentShell);
}
}
}
}
/**
* ExecuteCloseHandler - Run the close handler, if any.
* @return PR_TRUE iff we found a close handler to run.
*/
PRBool nsWebShellWindow::ExecuteCloseHandler()
{
/* If the event handler closes this window -- a likely scenario --
things get deleted out of order without this death grip.
(The problem may be the death grip in nsWindow::windowProc,
which forces this window's widget to remain alive longer
than it otherwise would.) */
nsCOMPtr<nsIWebShellWindow> kungFuDeathGrip(this);
nsresult rv;
nsCOMPtr<nsIScriptGlobalObjectOwner> globalObjectOwner(do_QueryInterface(mWebShell));
nsCOMPtr<nsIScriptGlobalObject> globalObject;
if (globalObjectOwner) {
if (NS_SUCCEEDED(globalObjectOwner->GetScriptGlobalObject(getter_AddRefs(globalObject))) && globalObject) {
nsCOMPtr<nsIContentViewer> contentViewer;
if (NS_SUCCEEDED(mWebShell->GetContentViewer(getter_AddRefs(contentViewer)))) {
nsCOMPtr<nsIDocumentViewer> docViewer;
nsCOMPtr<nsIPresContext> presContext;
docViewer = do_QueryInterface(contentViewer);
if (docViewer && NS_SUCCEEDED(docViewer->GetPresContext(*getter_AddRefs(presContext)))) {
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_EVENT;
event.message = NS_XUL_CLOSE;
rv = globalObject->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault)
return PR_TRUE;
// else fall through and return PR_FALSE
}
}
}
}
return PR_FALSE;
} // ExecuteCloseHandler
//----------------------------------------------------------------
//-- nsIDocumentObserver
//----------------------------------------------------------------
NS_IMETHODIMP
nsWebShellWindow::BeginUpdate(nsIDocument *aDocument)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::EndUpdate(nsIDocument *aDocument)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::BeginLoad(nsIDocument *aDocument)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::EndLoad(nsIDocument *aDocument)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::EndReflow(nsIDocument *aDocument, nsIPresShell* aShell)
{
return NS_OK;
}
///////////////////////////////////////////////////////////////
// nsIDocumentObserver
// this is needed for menu changes
///////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsWebShellWindow::ContentChanged(nsIDocument *aDocument,
nsIContent* aContent,
nsISupports* aSubContent)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::ContentStatesChanged(nsIDocument *aDocument,
nsIContent* aContent1,
nsIContent* aContent2)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::AttributeChanged(nsIDocument *aDocument,
nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
//printf("AttributeChanged\n");
PRInt32 i;
for (i=0;i<mMenuDelegates.Count();i++) {
nsIXULCommand * cmd = (nsIXULCommand *)mMenuDelegates[i];
nsIDOMElement * node;
cmd->GetDOMElement(&node);
//nsCOMPtr<nsIContent> content(do_QueryInterface(node));
// Doing this for the must speed
nsIContent * content;
if (NS_OK == node->QueryInterface(NS_GET_IID(nsIContent), (void**) &content)) {
if (content == aContent) {
nsAutoString attr;
aAttribute->ToString(attr);
cmd->AttributeHasBeenSet(attr);
}
NS_RELEASE(content);
}
}
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::ContentAppended(nsIDocument *aDocument,
nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::ContentInserted(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::ContentReplaced(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aOldChild,
nsIContent* aNewChild,
PRInt32 aIndexInContainer)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::ContentRemoved(nsIDocument *aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::StyleSheetAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::StyleSheetRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::StyleSheetDisabledStateChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
PRBool aDisabled)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::StyleRuleChanged(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule,
PRInt32 aHint)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::StyleRuleAdded(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::StyleRuleRemoved(nsIDocument *aDocument,
nsIStyleSheet* aStyleSheet,
nsIStyleRule* aStyleRule)
{
return NS_OK;
}
NS_IMETHODIMP
nsWebShellWindow::DocumentWillBeDestroyed(nsIDocument *aDocument)
{
return NS_OK;
}
/**************** nsIBrowserWindow interface ********************/
NS_IMETHODIMP nsWebShellWindow::Init(nsIAppShell* aAppShell,
nsIPref* aPrefs,
const nsRect& aBounds,
PRUint32 aChromeMask,
PRBool aAllowPlugins)
{
nsresult rv;
nsCOMPtr<nsIURI> urlObj;
char * urlStr = "chrome://navigator/content/";
NS_WITH_SERVICE(nsIIOService, service, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsIURI *uri = nsnull;
rv = service->NewURI(urlStr, nsnull, &uri);
if (NS_FAILED(rv)) return rv;
rv = uri->QueryInterface(NS_GET_IID(nsIURI), (void**)&urlObj);
NS_RELEASE(uri);
if (NS_FAILED(rv))
return rv;
// Note: null nsIStreamObserver means this window won't be able to answer FE_callback-type
// questions from netlib. Observers are generally appcores. We'll have to supply
// a generic browser appcore here someday.
nsWidgetInitData widgetInitData;
widgetInitData.mWindowType = eWindowType_child;
widgetInitData.mBorderStyle = eBorderStyle_default;
rv = Initialize(nsnull, aAppShell, urlObj, PR_TRUE, PR_TRUE,
nsnull, aBounds.width, aBounds.height, widgetInitData);
EnsureContentTreeOwner();
mContentTreeOwner->SetChromeMask(aChromeMask);
if (NS_SUCCEEDED(rv))
MoveTo(aBounds.x, aBounds.y);
return rv;
}
NS_IMETHODIMP nsWebShellWindow::MoveTo(PRInt32 aX, PRInt32 aY)
{
mWindow->Move(aX, aY);
StoreBoundsToXUL(PR_TRUE, PR_FALSE);
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::SizeWindowTo(PRInt32 aWidth, PRInt32 aHeight,
PRBool aWidthTransient, PRBool aHeightTransient)
{
mIntrinsicallySized = PR_FALSE; // We got changed. No more intrinsic sizing here.
if (aWidthTransient || aHeightTransient)
KillPersistentSize();
mWindow->Resize(aWidth, aHeight, PR_TRUE);
StoreBoundsToXUL(PR_FALSE, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::SizeContentTo(PRInt32 aWidth, PRInt32 aHeight)
{
// We have to look at the delta between our content shell's
// size and the size passed in and then resize ourselves based on that
// delta.
nsCOMPtr<nsIWebShell> content;
GetContentWebShell(getter_AddRefs(content));
nsCOMPtr<nsIBaseWindow> contentAsWin(do_QueryInterface(content));
if (contentAsWin) {
PRInt32 x, y, width, height,
widthDelta, heightDelta;
contentAsWin->GetPositionAndSize(&x, & y, &width, &height);
widthDelta = aWidth - width;
heightDelta = aHeight - height;
if (widthDelta != 0 || heightDelta != 0) {
nsRect windowBounds;
mWindow->GetBounds(windowBounds);
mWindow->Resize(windowBounds.width + widthDelta,
windowBounds.height + heightDelta,
PR_TRUE);
StoreBoundsToXUL(PR_FALSE, PR_TRUE);
}
}
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::GetContentBounds(nsRect& aResult)
{
// Should return the size of the content webshell.
nsCOMPtr<nsIWebShell> contentShell;
GetContentWebShell(getter_AddRefs(contentShell));
nsCOMPtr<nsIBaseWindow> contentShellAsWin(do_QueryInterface(contentShell));
if (!contentShellAsWin) {
NS_ERROR("Attempt to retrieve the content bounds for a window with no content.");
return NS_ERROR_FAILURE;
}
PRInt32 x,y,width,height;
contentShellAsWin->GetPositionAndSize(&x, &y, &width, &height);
aResult.x = x;
aResult.y = y;
aResult.width = width;
aResult.height = height;
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::GetWindowBounds(nsRect& aResult)
{
PRInt32 x, y, cx, cy;
GetPositionAndSize(&x, &y, &cx, &cy);
aResult.x = x;
aResult.y = y;
aResult.width = cx;
aResult.height = cy;
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::SetChrome(PRUint32 aNewChromeMask)
{
if(mContentTreeOwner)
return mContentTreeOwner->SetChromeMask(aNewChromeMask);
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::GetChrome(PRUint32& aChromeMaskResult)
{
if(mContentTreeOwner)
return mContentTreeOwner->GetChromeMask(&aChromeMaskResult);
return NS_OK;
}
NS_IMETHODIMP nsWebShellWindow::SetTitle(const PRUnichar* aTitle)
{
NS_ENSURE_SUCCESS(EnsureContentTreeOwner(), NS_ERROR_FAILURE);
return mContentTreeOwner->SetTitle(aTitle);
}
NS_IMETHODIMP nsWebShellWindow::GetTitle(PRUnichar** aResult)
{
// no, we didn't store the title for you. why so nosy?
return NS_ERROR_FAILURE;
}
// This should rightfully be somebody's PROGID?
// Will switch when the "app shell browser component" arrives.
static const char *prefix = "component://netscape/appshell/component/browser/window";
nsresult
nsWebShellWindow::NotifyObservers( const nsString &aTopic, const nsString &someData ) {
nsresult rv = NS_OK;
// Get observer service.
nsIObserverService *svc = 0;
rv = nsServiceManager::GetService( NS_OBSERVERSERVICE_PROGID,
NS_GET_IID(nsIObserverService),
(nsISupports**)&svc );
if ( NS_SUCCEEDED( rv ) && svc ) {
// Notify observers as instructed; the subject is "this" web shell window.
nsAutoString topic(prefix);
topic += ";";
topic += aTopic;
rv = svc->Notify( (nsIWebShellWindow*)this, topic.GetUnicode(), someData.GetUnicode() );
// Release the service.
nsServiceManager::ReleaseService( NS_OBSERVERSERVICE_PROGID, svc );
} else {
}
return rv;
}
NS_IMETHODIMP nsWebShellWindow::SetStatus(const PRUnichar* aStatus)
{
NS_ENSURE_SUCCESS(EnsureContentTreeOwner(), NS_ERROR_FAILURE);
return mContentTreeOwner->SetJSStatus(aStatus);
}
NS_IMETHODIMP nsWebShellWindow::GetStatus(const PRUnichar** aResult)
{
NS_ERROR("Can't use this anymore");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsWebShellWindow::SetDefaultStatus(const PRUnichar* aStatus)
{
NS_ENSURE_SUCCESS(EnsureContentTreeOwner(), NS_ERROR_FAILURE);
return mContentTreeOwner->SetJSDefaultStatus(aStatus);
}
NS_IMETHODIMP nsWebShellWindow::GetDefaultStatus(const PRUnichar** aResult)
{
NS_ERROR("Can't use this anymore");
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsWebShellWindow::SetProgress(PRInt32 aProgress, PRInt32 aProgressMax)
{
nsresult rv = NS_OK;
// Encode progress report in topic (there is no GetProgress for observers
// to query it).
char topic[32];
PR_snprintf( topic,
sizeof topic,
"%ld %ld",
(long)aProgress,
(long)aProgressMax );
// Broadcast progress info to interested parties.
rv = NotifyObservers( "progress", topic );
return rv;
}
NS_IMETHODIMP
nsWebShellWindow::IsIntrinsicallySized(PRBool& aResult)
{
return GetIntrinsicallySized(&aResult);
}
// nsIPrompt
NS_IMETHODIMP nsWebShellWindow::Alert(const PRUnichar *text)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
// todo, put that in a string bundle
nsString defaultTitle("Alert");
if ( NS_SUCCEEDED( rv ) )
rv = dialog->Alert( domWindow, defaultTitle.GetUnicode(),text );
return rv;
}
NS_IMETHODIMP nsWebShellWindow::Confirm(const PRUnichar *text, PRBool *_retval)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
nsString defaultTitle("Confirm");
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv = dialog->Confirm( domWindow, defaultTitle.GetUnicode(), text, _retval );
return rv;
}
NS_IMETHODIMP nsWebShellWindow::ConfirmCheck(const PRUnichar *text, const PRUnichar *checkMsg, PRBool *checkValue, PRBool *_retval)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
// todo, put that in a string bundle
nsString defaultTitle("Confirm");
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv =dialog->ConfirmCheck( domWindow,defaultTitle.GetUnicode(), text, checkMsg, checkValue, _retval );
return rv;
}
NS_IMETHODIMP nsWebShellWindow::UniversalDialog
(const PRUnichar *inTitleMessage,
const PRUnichar *inDialogTitle, /* e.g., alert, confirm, prompt, prompt password */
const PRUnichar *inMsg, /* main message for dialog */
const PRUnichar *inCheckboxMsg, /* message for checkbox */
const PRUnichar *inButton0Text, /* text for first button */
const PRUnichar *inButton1Text, /* text for second button */
const PRUnichar *inButton2Text, /* text for third button */
const PRUnichar *inButton3Text, /* text for fourth button */
const PRUnichar *inEditfield1Msg, /*message for first edit field */
const PRUnichar *inEditfield2Msg, /* message for second edit field */
PRUnichar **inoutEditfield1Value, /* initial and final value for first edit field */
PRUnichar **inoutEditfield2Value, /* initial and final value for second edit field */
const PRUnichar *inIConURL, /* url of icon to be displayed in dialog */
/* examples are
"chrome://global/skin/question-icon.gif" for question mark,
"chrome://global/skin/alert-icon.gif" for exclamation mark
*/
PRBool *inoutCheckboxState, /* initial and final state of check box */
PRInt32 inNumberButtons, /* total number of buttons (0 to 4) */
PRInt32 inNumberEditfields, /* total number of edit fields (0 to 2) */
PRInt32 inEditField1Password, /* is first edit field a password field */
PRInt32 *outButtonPressed) /* number of button that was pressed (0 to 3) */
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv = dialog->UniversalDialog(
domWindow, inTitleMessage, inDialogTitle, inMsg, inCheckboxMsg,
inButton0Text, inButton1Text, inButton2Text, inButton3Text,
inEditfield1Msg, inEditfield2Msg, inoutEditfield1Value,
inoutEditfield2Value, inIConURL, inoutCheckboxState, inNumberButtons,
inNumberEditfields, inEditField1Password, outButtonPressed);
return rv;
}
NS_IMETHODIMP nsWebShellWindow::Prompt(const PRUnichar *text, const PRUnichar *defaultText, PRUnichar **result, PRBool *_retval)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
// todo, put that in a string bundle
nsString defaultTitle("Prompt");
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv = dialog->Prompt( domWindow, defaultTitle.GetUnicode(), text, defaultText, result, _retval );
return rv;
}
NS_IMETHODIMP nsWebShellWindow::PromptUsernameAndPassword(const PRUnichar *text, PRUnichar **user, PRUnichar **pwd, PRBool *_retval)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
// todo, put that in a string bundle
nsString defaultTitle("Prompt Username and Password");
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv = dialog->PromptUsernameAndPassword( domWindow, defaultTitle.GetUnicode(), text, user, pwd, _retval );
return rv;
}
NS_IMETHODIMP nsWebShellWindow::PromptPassword(const PRUnichar *text, const PRUnichar *title, PRUnichar **pwd, PRBool *_retval)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv = dialog->PromptPassword( domWindow, title, text, pwd, _retval );
return rv;
}
NS_IMETHODIMP nsWebShellWindow::Select( const PRUnichar *inDialogTitle, const PRUnichar* inMsg, PRUint32 inCount, const PRUnichar **inList, PRInt32 *outSelection, PRBool *_retval)
{
nsresult rv;
nsCOMPtr<nsIDOMWindow> domWindow;
nsIWebShell* tempWebShell;
GetWebShell(tempWebShell );
nsCOMPtr<nsIWebShell> webShell( dont_AddRef(tempWebShell) );
if (NS_FAILED(rv = ConvertWebShellToDOMWindow(webShell, getter_AddRefs(domWindow))))
{
NS_ERROR("Unable to retrieve the DOM window from the new web shell.");
return rv;
}
NS_WITH_SERVICE(nsICommonDialogs, dialog, kCommonDialogsCID, &rv);
if ( NS_SUCCEEDED( rv ) )
rv = dialog->Select(domWindow, inDialogTitle, inMsg, inCount,inList, outSelection, _retval);
return rv;
}
NS_IMETHODIMP nsWebShellWindow::Alert(const char *url, PRBool stripUrl, const PRUnichar *title, const PRUnichar *text)
{
return Alert( text );
}
NS_IMETHODIMP nsWebShellWindow::Confirm(const char *url, PRBool stripUrl, const PRUnichar *title, const PRUnichar *text, PRBool *_retval)
{
return Confirm( text, _retval );
}
NS_IMETHODIMP nsWebShellWindow::PromptUsernameAndPassword(const char *url, PRBool stripUrl, const PRUnichar *title, const PRUnichar *text, PRUnichar **user, PRUnichar **pwd, PRBool *_retval)
{
nsresult res;
NS_WITH_SERVICE(nsIWalletService, wallet, kWalletServiceCID, &res);
if (NS_FAILED(res)) {
return PromptUsernameAndPassword(text,user, pwd, _retval);
}
nsCOMPtr<nsIPrompt> prompter = this;
return wallet->PromptUsernameAndPasswordURL(text,user, pwd, url, stripUrl, prompter, _retval);
}
NS_IMETHODIMP nsWebShellWindow::PromptPassword(const char *url, PRBool stripUrl, const PRUnichar *title, const PRUnichar *text, PRUnichar **pwd, PRBool *_retval)
{
nsresult res;
NS_WITH_SERVICE(nsIWalletService, wallet, kWalletServiceCID, &res);
if (NS_FAILED(res)) {
return PromptPassword(text, title, pwd, _retval);
}
nsCOMPtr<nsIPrompt> prompter = this;
return wallet->PromptPasswordURL(text, pwd, url, stripUrl, prompter, _retval);
}
NS_IMETHODIMP nsWebShellWindow::Prompt(const char *url, PRBool stripUrl, const PRUnichar *title, const PRUnichar *text, PRUnichar **value, PRBool *_retval)
{
nsresult res;
NS_WITH_SERVICE(nsIWalletService, wallet, kWalletServiceCID, &res);
if (NS_FAILED(res)) {
return Prompt(text, title, value, _retval);
}
nsCOMPtr<nsIPrompt> prompter = this;
return wallet->PromptURL(text, nsnull, value, url, stripUrl, prompter, _retval);
}