Back to index

lightning-sunbird  0.9+nobinonly
nsWebBrowser.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is the Mozilla browser.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications, Inc.
00020  * Portions created by the Initial Developer are Copyright (C) 1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Travis Bogard <travis@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 // Local Includes
00041 #include "nsWebBrowser.h"
00042 
00043 // Helper Classes
00044 #include "nsGfxCIID.h"
00045 #include "nsWidgetsCID.h"
00046 
00047 //Interfaces Needed
00048 #include "nsReadableUtils.h"
00049 #include "nsIComponentManager.h"
00050 #include "nsIDocument.h"
00051 #include "nsIDOMDocument.h"
00052 #include "nsIDOMXULDocument.h"
00053 #include "nsIDOMWindow.h"
00054 #include "nsIDOMElement.h"
00055 #include "nsIInterfaceRequestor.h"
00056 #include "nsIInterfaceRequestorUtils.h"
00057 #include "nsIWebBrowserChrome.h"
00058 #include "nsPIDOMWindow.h"
00059 #include "nsIFocusController.h"
00060 #include "nsIDOMWindowInternal.h"
00061 #include "nsIWebProgress.h"
00062 #include "nsIWebProgressListener.h"
00063 #include "nsIWebBrowserFocus.h"
00064 #include "nsIWebBrowserStream.h"
00065 #include "nsIPresShell.h"
00066 #include "nsIGlobalHistory.h"
00067 #include "nsIDocShellHistory.h"
00068 #include "nsIURIContentListener.h"
00069 #include "nsGUIEvent.h"
00070 #include "nsISHistoryListener.h"
00071 #include "nsIURI.h"
00072 #include "nsIWebBrowserPersist.h"
00073 #include "nsCWebBrowserPersist.h"
00074 #include "nsIWebBrowserPrint.h"
00075 #include "nsIServiceManager.h"
00076 
00077 // for painting the background window
00078 #include "nsIRenderingContext.h"
00079 #include "nsIRegion.h"
00080 #include "nsILookAndFeel.h"
00081 
00082 // Printing Includes
00083 #include "nsIContentViewer.h"
00084 
00085 // PSM2 includes
00086 #include "nsISecureBrowserUI.h"
00087 
00088 #if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
00089 #include <MacWindows.h>
00090 #include "nsWidgetSupport.h"
00091 #include "nsIEventSink.h"
00092 #endif
00093 
00094 static NS_DEFINE_IID(kWindowCID, NS_WINDOW_CID);
00095 static NS_DEFINE_CID(kChildCID, NS_CHILD_CID);
00096 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
00097 
00098 
00099 //*****************************************************************************
00100 //***    nsWebBrowser: Object Management
00101 //*****************************************************************************
00102 
00103 nsWebBrowser::nsWebBrowser() : mDocShellTreeOwner(nsnull), 
00104    mInitInfo(nsnull),
00105    mContentType(typeContentWrapper),
00106    mActivating(PR_FALSE),
00107    mParentNativeWindow(nsnull),
00108    mProgressListener(nsnull),
00109    mBackgroundColor(0),
00110    mPersistCurrentState(nsIWebBrowserPersist::PERSIST_STATE_READY),
00111    mPersistResult(NS_OK),
00112    mPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_NONE),
00113    mStream(nsnull),
00114    mParentWidget(nsnull),
00115    mListenerArray(nsnull)
00116 #if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
00117    , mTopLevelWidget(nsnull)
00118 #endif
00119 {
00120     mInitInfo = new nsWebBrowserInitInfo();
00121     mWWatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
00122     NS_ASSERTION(mWWatch, "failed to get WindowWatcher");
00123 }
00124 
00125 nsWebBrowser::~nsWebBrowser()
00126 {
00127    InternalDestroy();
00128 }
00129 
00130 PRBool PR_CALLBACK deleteListener(void *aElement, void *aData) {
00131     nsWebBrowserListenerState *state = (nsWebBrowserListenerState*)aElement;
00132     NS_DELETEXPCOM(state);
00133     return PR_TRUE;
00134 }
00135 
00136 NS_IMETHODIMP nsWebBrowser::InternalDestroy()
00137 {
00138 
00139   if (mInternalWidget)
00140     mInternalWidget->SetClientData(0);
00141 
00142    SetDocShell(nsnull);
00143 
00144    if(mDocShellTreeOwner)
00145       {
00146       mDocShellTreeOwner->WebBrowser(nsnull);
00147       NS_RELEASE(mDocShellTreeOwner);
00148       }
00149    if(mInitInfo)
00150       {
00151       delete mInitInfo;
00152       mInitInfo = nsnull;
00153       }
00154 
00155    if (mListenerArray) {
00156       (void)mListenerArray->EnumerateForwards(deleteListener, nsnull);
00157       delete mListenerArray;
00158       mListenerArray = nsnull;
00159    }
00160 
00161 #if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)   
00162    NS_IF_RELEASE(mTopLevelWidget);
00163 #endif
00164 
00165    return NS_OK;
00166 }
00167 
00168 
00169 //*****************************************************************************
00170 // nsWebBrowser::nsISupports
00171 //*****************************************************************************   
00172 
00173 NS_IMPL_ADDREF(nsWebBrowser)
00174 NS_IMPL_RELEASE(nsWebBrowser)
00175 
00176 NS_INTERFACE_MAP_BEGIN(nsWebBrowser)
00177     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowser)
00178     NS_INTERFACE_MAP_ENTRY(nsIWebBrowser)
00179     NS_INTERFACE_MAP_ENTRY(nsIWebNavigation)
00180     NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
00181     NS_INTERFACE_MAP_ENTRY(nsIScrollable)
00182     NS_INTERFACE_MAP_ENTRY(nsITextScroll)
00183     NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeItem)
00184     NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
00185     NS_INTERFACE_MAP_ENTRY(nsIWebBrowserSetup)
00186     NS_INTERFACE_MAP_ENTRY(nsIWebBrowserPersist)
00187     NS_INTERFACE_MAP_ENTRY(nsICancelable)
00188     NS_INTERFACE_MAP_ENTRY(nsIWebBrowserFocus)
00189     NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
00190     NS_INTERFACE_MAP_ENTRY(nsIWebBrowserStream)
00191     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
00192 NS_INTERFACE_MAP_END
00193 
00195 // nsWebBrowser::nsIInterfaceRequestor
00196 //*****************************************************************************   
00197 
00198 NS_IMETHODIMP nsWebBrowser::GetInterface(const nsIID& aIID, void** aSink)
00199 {
00200    NS_ENSURE_ARG_POINTER(aSink);
00201 
00202    if(NS_SUCCEEDED(QueryInterface(aIID, aSink)))
00203       return NS_OK;
00204 
00205 #if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
00206    if (aIID.Equals(NS_GET_IID(nsIEventSink)) && mTopLevelWidget)
00207       return mTopLevelWidget->QueryInterface(NS_GET_IID(nsIEventSink), aSink);
00208 #endif
00209 
00210    if (mDocShell) {
00211        if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
00212            nsCOMPtr<nsIContentViewer> viewer;
00213            mDocShell->GetContentViewer(getter_AddRefs(viewer));
00214            if (viewer) {
00215                nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint(do_QueryInterface(viewer));
00216                nsIWebBrowserPrint* print = (nsIWebBrowserPrint*)webBrowserPrint.get();
00217                NS_ASSERTION(print, "This MUST support this interface!");
00218                NS_ADDREF(print);
00219                *aSink = print;
00220                return NS_OK;
00221            }
00222        } else {
00223            return mDocShellAsReq->GetInterface(aIID, aSink);
00224        }
00225    }
00226 
00227    return NS_NOINTERFACE;
00228 }
00229 
00230 //*****************************************************************************
00231 // nsWebBrowser::nsIWebBrowser
00232 //*****************************************************************************   
00233 
00234 // listeners that currently support registration through AddWebBrowserListener:
00235 //  - nsIWebProgressListener
00236 NS_IMETHODIMP nsWebBrowser::AddWebBrowserListener(nsIWeakReference *aListener, const nsIID& aIID)
00237 {           
00238     NS_ENSURE_ARG_POINTER(aListener);
00239 
00240     nsresult rv = NS_OK;
00241     if (!mWebProgress) {
00242         // The window hasn't been created yet, so queue up the listener. They'll be
00243         // registered when the window gets created.
00244         nsAutoPtr<nsWebBrowserListenerState> state;
00245         NS_NEWXPCOM(state, nsWebBrowserListenerState);
00246         if (!state) return NS_ERROR_OUT_OF_MEMORY;
00247 
00248         state->mWeakPtr = aListener;
00249         state->mID = aIID;
00250 
00251         if (!mListenerArray) {
00252             NS_NEWXPCOM(mListenerArray, nsVoidArray);
00253             if (!mListenerArray) {
00254                 return NS_ERROR_OUT_OF_MEMORY;
00255             }
00256         }
00257 
00258         if (!mListenerArray->AppendElement(state)) {
00259             return NS_ERROR_OUT_OF_MEMORY;
00260         }
00261 
00262         // We're all set now; don't delete |state| after this point
00263         state.forget();
00264     } else {
00265         nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
00266         if (!supports) return NS_ERROR_INVALID_ARG;
00267         rv = BindListener(supports, aIID);
00268     }
00269     
00270     return rv;
00271 }
00272 
00273 NS_IMETHODIMP nsWebBrowser::BindListener(nsISupports *aListener, const nsIID& aIID) {
00274     NS_ASSERTION(aListener, "invalid args");
00275     NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface");
00276     nsresult rv = NS_OK;
00277 
00278     // register this listener for the specified interface id
00279     if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
00280         nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
00281         if (NS_FAILED(rv)) return rv;
00282         rv = mWebProgress->AddProgressListener(listener, nsIWebProgress::NOTIFY_ALL);
00283     }
00284     else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {      
00285       nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
00286       if (NS_FAILED(rv)) return rv;
00287       nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
00288       if (NS_FAILED(rv)) return rv;
00289       rv = shistory->AddSHistoryListener(listener);
00290     }
00291     return rv;
00292 }
00293 
00294 NS_IMETHODIMP nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference *aListener, const nsIID& aIID)
00295 {
00296     NS_ENSURE_ARG_POINTER(aListener);
00297 
00298     nsresult rv = NS_OK;
00299     if (!mWebProgress) {
00300         // if there's no-one to register the listener w/, and we don't have a queue going,
00301         // the the called is calling Remove before an Add which doesn't make sense.
00302         if (!mListenerArray) return NS_ERROR_FAILURE;
00303 
00304         // iterate the array and remove the queued listener
00305         PRInt32 count = mListenerArray->Count();
00306         while (count > 0) {
00307             nsWebBrowserListenerState *state = (nsWebBrowserListenerState*)mListenerArray->ElementAt(count);
00308             NS_ASSERTION(state, "list construction problem");
00309 
00310             if (state->Equals(aListener, aIID)) {
00311                 // this is the one, pull it out.
00312                 mListenerArray->RemoveElementAt(count);
00313                 break;
00314             }
00315             count--; 
00316         }
00317 
00318         // if we've emptied the array, get rid of it.
00319         if (0 >= mListenerArray->Count()) {
00320             (void)mListenerArray->EnumerateForwards(deleteListener, nsnull);
00321             NS_DELETEXPCOM(mListenerArray);
00322             mListenerArray = nsnull;
00323         }
00324 
00325     } else {
00326         nsCOMPtr<nsISupports> supports(do_QueryReferent(aListener));
00327         if (!supports) return NS_ERROR_INVALID_ARG;
00328         rv = UnBindListener(supports, aIID);
00329     }
00330     
00331     return rv;
00332 }
00333 
00334 NS_IMETHODIMP nsWebBrowser::UnBindListener(nsISupports *aListener, const nsIID& aIID) {
00335     NS_ASSERTION(aListener, "invalid args");
00336     NS_ASSERTION(mWebProgress, "this should only be called after we've retrieved a progress iface");
00337     nsresult rv = NS_OK;
00338 
00339     // remove the listener for the specified interface id
00340     if (aIID.Equals(NS_GET_IID(nsIWebProgressListener))) {
00341         nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(aListener, &rv);
00342         if (NS_FAILED(rv)) return rv;
00343         rv = mWebProgress->RemoveProgressListener(listener);
00344     }
00345     else if (aIID.Equals(NS_GET_IID(nsISHistoryListener))) {
00346       nsCOMPtr<nsISHistory> shistory(do_GetInterface(mDocShell, &rv));
00347       if (NS_FAILED(rv)) return rv;
00348       nsCOMPtr<nsISHistoryListener> listener(do_QueryInterface(aListener, &rv));
00349       if (NS_FAILED(rv)) return rv;
00350       rv = shistory->RemoveSHistoryListener(listener);
00351     }
00352     return rv;
00353 }
00354 
00355 NS_IMETHODIMP nsWebBrowser::EnableGlobalHistory(PRBool aEnable)
00356 {
00357     nsresult rv;
00358     
00359     NS_ENSURE_STATE(mDocShell);
00360     nsCOMPtr<nsIDocShellHistory> dsHistory(do_QueryInterface(mDocShell, &rv));
00361     if (NS_FAILED(rv)) return rv;
00362     
00363     if (aEnable) {
00364         rv = dsHistory->SetUseGlobalHistory(PR_TRUE);
00365     }
00366     else {
00367         rv = dsHistory->SetUseGlobalHistory(PR_FALSE);
00368     }
00369        
00370     return rv;
00371 }
00372 
00373 #if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
00374 NS_IMETHODIMP nsWebBrowser::EnsureTopLevelWidget(nativeWindow aWindow)
00375 {
00376     WindowPtr macWindow = NS_STATIC_CAST(WindowPtr, aWindow);
00377     nsIWidget *widget = nsnull;
00378     nsCOMPtr<nsIWidget> newWidget;
00379     nsresult rv = NS_ERROR_FAILURE;
00380 
00381     ::GetWindowProperty(macWindow, kTopLevelWidgetPropertyCreator,
00382         kTopLevelWidgetRefPropertyTag, sizeof(nsIWidget*), nsnull, (void*)&widget);
00383     if (!widget) {
00384       newWidget = do_CreateInstance(kWindowCID, &rv);
00385       if (NS_SUCCEEDED(rv)) {
00386         
00387         // Create it with huge bounds. The actual bounds that matters is that of the
00388         // nsIBaseWindow. The bounds of the top level widget clips its children so
00389         // we just have to make sure it is big enough to always contain the children.
00390 
00391         nsRect r(0, 0, 32000, 32000);
00392         rv = newWidget->Create(macWindow, r, nsnull, nsnull, nsnull, nsnull, nsnull);
00393         if (NS_SUCCEEDED(rv))
00394           widget = newWidget;
00395       }
00396     }
00397     NS_ASSERTION(widget, "Failed to get or create a toplevel widget!!");
00398     if (widget) {
00399       mTopLevelWidget = widget;
00400       NS_ADDREF(mTopLevelWidget); // Allows multiple nsWebBrowsers to be in 1 window.
00401       rv = NS_OK;
00402     }
00403     return rv;
00404 }
00405 #endif
00406 
00407 NS_IMETHODIMP nsWebBrowser::GetContainerWindow(nsIWebBrowserChrome** aTopWindow)
00408 {
00409    NS_ENSURE_ARG_POINTER(aTopWindow);
00410 
00411    if(mDocShellTreeOwner) {
00412       *aTopWindow = mDocShellTreeOwner->GetWebBrowserChrome().get();
00413    } else {
00414       *aTopWindow = nsnull;
00415    }
00416 
00417    return NS_OK;
00418 }
00419 
00420 NS_IMETHODIMP nsWebBrowser::SetContainerWindow(nsIWebBrowserChrome* aTopWindow)
00421 {
00422    NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
00423    return mDocShellTreeOwner->SetWebBrowserChrome(aTopWindow);
00424 }
00425 
00426 NS_IMETHODIMP nsWebBrowser::GetParentURIContentListener(nsIURIContentListener**
00427    aParentContentListener)
00428 {
00429    NS_ENSURE_ARG_POINTER(aParentContentListener);
00430    *aParentContentListener = nsnull;
00431 
00432    // get the interface from the docshell
00433    nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
00434 
00435    if (listener)
00436        return listener->GetParentContentListener(aParentContentListener);
00437    return NS_OK;
00438 }
00439 
00440 NS_IMETHODIMP nsWebBrowser::SetParentURIContentListener(nsIURIContentListener*
00441    aParentContentListener)
00442 {
00443    // get the interface from the docshell
00444    nsCOMPtr<nsIURIContentListener> listener(do_GetInterface(mDocShell));
00445 
00446    if (listener)
00447        return listener->SetParentContentListener(aParentContentListener);
00448    return NS_ERROR_FAILURE;
00449 }
00450 
00451 NS_IMETHODIMP nsWebBrowser::GetContentDOMWindow(nsIDOMWindow **_retval)
00452 {
00453     NS_ENSURE_STATE(mDocShell);
00454     nsresult rv = NS_OK;
00455     nsCOMPtr<nsIDOMWindow> retval = do_GetInterface(mDocShell, &rv);
00456     if (NS_FAILED(rv)) return rv;
00457 
00458     *_retval = retval;
00459     NS_ADDREF(*_retval);
00460     return rv;
00461 }
00462 
00463 //*****************************************************************************
00464 // nsWebBrowser::nsIDocShellTreeItem
00465 //*****************************************************************************   
00466 
00467 NS_IMETHODIMP nsWebBrowser::GetName(PRUnichar** aName)
00468 {
00469    NS_ENSURE_ARG_POINTER(aName);
00470 
00471    if(mDocShell)  
00472       mDocShellAsItem->GetName(aName);
00473    else
00474       *aName = ToNewUnicode(mInitInfo->name);
00475 
00476    return NS_OK;
00477 }
00478 
00479 NS_IMETHODIMP nsWebBrowser::SetName(const PRUnichar* aName)
00480 {
00481    if(mDocShell)
00482       {
00483       nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
00484       NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
00485 
00486       return docShellAsItem->SetName(aName);
00487       }
00488    else
00489       mInitInfo->name = aName;
00490 
00491    return NS_OK;
00492 }
00493 
00494 NS_IMETHODIMP nsWebBrowser::NameEquals(const PRUnichar *aName, PRBool *_retval)
00495 {
00496     NS_ENSURE_ARG_POINTER(aName);
00497     NS_ENSURE_ARG_POINTER(_retval);
00498     if(mDocShell)
00499     {
00500         nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
00501         NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
00502         return docShellAsItem->NameEquals(aName, _retval);
00503     }
00504     else
00505         *_retval = mInitInfo->name.Equals(aName);
00506 
00507     return NS_OK;
00508 }
00509 
00510 NS_IMETHODIMP nsWebBrowser::GetItemType(PRInt32* aItemType)
00511 {
00512    NS_ENSURE_ARG_POINTER(aItemType);
00513 
00514    *aItemType = mContentType;
00515    return NS_OK;
00516 }
00517 
00518 NS_IMETHODIMP nsWebBrowser::SetItemType(PRInt32 aItemType)
00519 {
00520     NS_ENSURE_TRUE((aItemType == typeContentWrapper || aItemType == typeChromeWrapper), NS_ERROR_FAILURE);
00521     mContentType = aItemType;
00522     if (mDocShellAsItem)
00523         mDocShellAsItem->SetItemType(mContentType == typeChromeWrapper ? typeChrome : typeContent);
00524     return NS_OK;
00525 }
00526 
00527 NS_IMETHODIMP nsWebBrowser::GetParent(nsIDocShellTreeItem** aParent)
00528 {
00529    *aParent = nsnull;
00530    return NS_OK;
00531 }
00532 
00533 NS_IMETHODIMP nsWebBrowser::GetSameTypeParent(nsIDocShellTreeItem** aParent)
00534 {
00535    *aParent = nsnull;
00536 
00537    return NS_OK;
00538 }
00539 
00540 NS_IMETHODIMP nsWebBrowser::GetRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
00541 {
00542    NS_ENSURE_ARG_POINTER(aRootTreeItem);
00543    *aRootTreeItem = NS_STATIC_CAST(nsIDocShellTreeItem*, this);
00544 
00545    nsCOMPtr<nsIDocShellTreeItem> parent;
00546    NS_ENSURE_SUCCESS(GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
00547    while(parent)
00548       {
00549       *aRootTreeItem = parent;
00550       NS_ENSURE_SUCCESS((*aRootTreeItem)->GetParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
00551       }
00552    NS_ADDREF(*aRootTreeItem);
00553    return NS_OK;
00554 }
00555 
00556 NS_IMETHODIMP nsWebBrowser::GetSameTypeRootTreeItem(nsIDocShellTreeItem** aRootTreeItem)
00557 {
00558    NS_ENSURE_ARG_POINTER(aRootTreeItem);
00559    *aRootTreeItem = NS_STATIC_CAST(nsIDocShellTreeItem*, this);
00560 
00561    nsCOMPtr<nsIDocShellTreeItem> parent;
00562    NS_ENSURE_SUCCESS(GetSameTypeParent(getter_AddRefs(parent)), NS_ERROR_FAILURE);
00563    while(parent)
00564       {
00565       *aRootTreeItem = parent;
00566       NS_ENSURE_SUCCESS((*aRootTreeItem)->GetSameTypeParent(getter_AddRefs(parent)), 
00567          NS_ERROR_FAILURE);
00568       }
00569    NS_ADDREF(*aRootTreeItem);
00570    return NS_OK;
00571 }
00572 
00573 NS_IMETHODIMP nsWebBrowser::FindItemWithName(const PRUnichar *aName, 
00574    nsISupports* aRequestor, nsIDocShellTreeItem* aOriginalRequestor,
00575    nsIDocShellTreeItem **_retval)
00576 {
00577    NS_ENSURE_STATE(mDocShell);
00578    NS_ASSERTION(mDocShellTreeOwner, "This should always be set when in this situation");
00579 
00580    return mDocShellAsItem->FindItemWithName(aName, 
00581       NS_STATIC_CAST(nsIDocShellTreeOwner*, mDocShellTreeOwner),
00582       aOriginalRequestor, _retval);
00583 }
00584 
00585 NS_IMETHODIMP nsWebBrowser::GetTreeOwner(nsIDocShellTreeOwner** aTreeOwner)
00586 {  
00587     NS_ENSURE_ARG_POINTER(aTreeOwner);
00588     *aTreeOwner = nsnull;
00589     if(mDocShellTreeOwner)
00590     {
00591         if (mDocShellTreeOwner->mTreeOwner)
00592         {
00593             *aTreeOwner = mDocShellTreeOwner->mTreeOwner;
00594         }
00595         else
00596         {
00597             *aTreeOwner = mDocShellTreeOwner;
00598         }
00599     }
00600     NS_IF_ADDREF(*aTreeOwner);
00601     return NS_OK;
00602 }
00603 
00604 NS_IMETHODIMP nsWebBrowser::SetTreeOwner(nsIDocShellTreeOwner* aTreeOwner)
00605 {
00606    NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
00607    return mDocShellTreeOwner->SetTreeOwner(aTreeOwner);
00608 }
00609 
00610 NS_IMETHODIMP nsWebBrowser::SetChildOffset(PRInt32 aChildOffset)
00611 {
00612   // Not implemented
00613   return NS_OK;
00614 }
00615 
00616 NS_IMETHODIMP nsWebBrowser::GetChildOffset(PRInt32 *aChildOffset)
00617 {
00618   // Not implemented
00619   return NS_OK;
00620 }
00621 
00622 //*****************************************************************************
00623 // nsWebBrowser::nsIWebNavigation
00624 //*****************************************************************************
00625 
00626 NS_IMETHODIMP nsWebBrowser::GetCanGoBack(PRBool* aCanGoBack)
00627 {
00628    NS_ENSURE_STATE(mDocShell);
00629 
00630    return mDocShellAsNav->GetCanGoBack(aCanGoBack);
00631 }
00632 
00633 NS_IMETHODIMP nsWebBrowser::GetCanGoForward(PRBool* aCanGoForward)
00634 {
00635    NS_ENSURE_STATE(mDocShell);
00636 
00637    return mDocShellAsNav->GetCanGoForward(aCanGoForward);
00638 }
00639 
00640 NS_IMETHODIMP nsWebBrowser::GoBack()
00641 {
00642    NS_ENSURE_STATE(mDocShell);
00643 
00644    return mDocShellAsNav->GoBack();
00645 }
00646 
00647 NS_IMETHODIMP nsWebBrowser::GoForward()
00648 {
00649    NS_ENSURE_STATE(mDocShell);
00650 
00651    return mDocShellAsNav->GoForward();
00652 }
00653 
00654 NS_IMETHODIMP nsWebBrowser::LoadURI(const PRUnichar* aURI,
00655                                     PRUint32 aLoadFlags,
00656                                     nsIURI* aReferringURI,
00657                                     nsIInputStream* aPostDataStream,
00658                                     nsIInputStream* aExtraHeaderStream)
00659 {
00660    NS_ENSURE_STATE(mDocShell);
00661 
00662    return mDocShellAsNav->LoadURI(aURI,
00663                                   aLoadFlags,
00664                                   aReferringURI,
00665                                   aPostDataStream,
00666                                   aExtraHeaderStream);
00667 }
00668 
00669 NS_IMETHODIMP nsWebBrowser::Reload(PRUint32 aReloadFlags)
00670 {
00671    NS_ENSURE_STATE(mDocShell);
00672 
00673    return mDocShellAsNav->Reload(aReloadFlags);
00674 }
00675 
00676 NS_IMETHODIMP nsWebBrowser::GotoIndex(PRInt32 aIndex)
00677 {
00678    NS_ENSURE_STATE(mDocShell);
00679 
00680    return mDocShellAsNav->GotoIndex(aIndex);
00681 }
00682 
00683 NS_IMETHODIMP nsWebBrowser::Stop(PRUint32 aStopFlags)
00684 {
00685    NS_ENSURE_STATE(mDocShell);
00686 
00687    return mDocShellAsNav->Stop(aStopFlags);
00688 }
00689 
00690 NS_IMETHODIMP nsWebBrowser::GetCurrentURI(nsIURI** aURI)
00691 {
00692    NS_ENSURE_STATE(mDocShell);
00693 
00694    return mDocShellAsNav->GetCurrentURI(aURI);
00695 }
00696 
00697 NS_IMETHODIMP nsWebBrowser::GetReferringURI(nsIURI** aURI)
00698 {
00699     NS_ENSURE_STATE(mDocShell);
00700 
00701     return mDocShellAsNav->GetReferringURI(aURI);
00702 }
00703 
00704 NS_IMETHODIMP nsWebBrowser::SetSessionHistory(nsISHistory* aSessionHistory)
00705 {
00706    if(mDocShell)
00707       return mDocShellAsNav->SetSessionHistory(aSessionHistory);
00708    else
00709       mInitInfo->sessionHistory = aSessionHistory;
00710 
00711    return NS_OK;
00712 }
00713 
00714 NS_IMETHODIMP nsWebBrowser::GetSessionHistory(nsISHistory** aSessionHistory)
00715 {
00716    NS_ENSURE_ARG_POINTER(aSessionHistory);
00717    if(mDocShell)
00718       return mDocShellAsNav->GetSessionHistory(aSessionHistory);
00719    else
00720       *aSessionHistory = mInitInfo->sessionHistory;
00721 
00722    NS_IF_ADDREF(*aSessionHistory);
00723 
00724    return NS_OK;
00725 }
00726 
00727 
00728 NS_IMETHODIMP nsWebBrowser::GetDocument(nsIDOMDocument** aDocument)
00729 {
00730    NS_ENSURE_STATE(mDocShell);
00731 
00732    return mDocShellAsNav->GetDocument(aDocument);
00733 }
00734 
00735 
00736 //*****************************************************************************
00737 // nsWebBrowser::nsIWebBrowserSetup
00738 //*****************************************************************************
00739 
00740 /* void setProperty (in unsigned long aId, in unsigned long aValue); */
00741 NS_IMETHODIMP nsWebBrowser::SetProperty(PRUint32 aId, PRUint32 aValue)
00742 {
00743     nsresult rv = NS_OK;
00744     
00745     switch (aId)
00746     {
00747     case nsIWebBrowserSetup::SETUP_ALLOW_PLUGINS:
00748         {
00749            NS_ENSURE_STATE(mDocShell);
00750            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00751            mDocShell->SetAllowPlugins(aValue);
00752         }
00753         break;
00754     case nsIWebBrowserSetup::SETUP_ALLOW_JAVASCRIPT:
00755         {
00756            NS_ENSURE_STATE(mDocShell);
00757            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00758            mDocShell->SetAllowJavascript(aValue);
00759         }
00760         break;
00761     case nsIWebBrowserSetup::SETUP_ALLOW_META_REDIRECTS:
00762         {
00763            NS_ENSURE_STATE(mDocShell);
00764            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00765            mDocShell->SetAllowMetaRedirects(aValue);
00766         }
00767         break;
00768     case nsIWebBrowserSetup::SETUP_ALLOW_SUBFRAMES:
00769         {
00770            NS_ENSURE_STATE(mDocShell);
00771            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00772            mDocShell->SetAllowSubframes(aValue);
00773         }
00774         break;
00775     case nsIWebBrowserSetup::SETUP_ALLOW_IMAGES:
00776         {
00777            NS_ENSURE_STATE(mDocShell);
00778            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00779            mDocShell->SetAllowImages(aValue);
00780         }
00781         break;
00782     case nsIWebBrowserSetup::SETUP_USE_GLOBAL_HISTORY:
00783         {
00784            NS_ENSURE_STATE(mDocShell);
00785            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00786            rv = EnableGlobalHistory(aValue);
00787         }
00788         break;
00789     case nsIWebBrowserSetup::SETUP_FOCUS_DOC_BEFORE_CONTENT:
00790         {
00791             // obsolete
00792         }
00793         break;
00794     case nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER:
00795         {
00796            NS_ENSURE_TRUE((aValue == PR_TRUE || aValue == PR_FALSE), NS_ERROR_INVALID_ARG);
00797            SetItemType(aValue ? typeChromeWrapper : typeContentWrapper);
00798         }
00799         break;
00800     default:
00801         rv = NS_ERROR_INVALID_ARG;
00802   
00803     }
00804     return rv;
00805 }
00806 
00807 
00808 //*****************************************************************************
00809 // nsWebBrowser::nsIWebProgressListener
00810 //*****************************************************************************
00811 
00812 /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long aStateFlags, in nsresult aStatus); */
00813 NS_IMETHODIMP nsWebBrowser::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
00814 {
00815     if (mPersist)
00816     {
00817         mPersist->GetCurrentState(&mPersistCurrentState);
00818     }
00819     if (aStateFlags & STATE_IS_NETWORK && aStateFlags & STATE_STOP)
00820     {
00821         mPersist = nsnull;
00822     }
00823     if (mProgressListener)
00824     {
00825         return mProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
00826     }
00827     return NS_OK;
00828 }
00829 
00830 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
00831 NS_IMETHODIMP nsWebBrowser::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
00832 {
00833     if (mPersist)
00834     {
00835         mPersist->GetCurrentState(&mPersistCurrentState);
00836     }
00837     if (mProgressListener)
00838     {
00839         return mProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
00840     }
00841     return NS_OK;
00842 }
00843 
00844 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
00845 NS_IMETHODIMP nsWebBrowser::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
00846 {
00847     if (mProgressListener)
00848     {
00849         return mProgressListener->OnLocationChange(aWebProgress, aRequest, location);
00850     }
00851     return NS_OK;
00852 }
00853 
00854 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
00855 NS_IMETHODIMP nsWebBrowser::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
00856 {
00857     if (mProgressListener)
00858     {
00859         return mProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
00860     }
00861     return NS_OK;
00862 }
00863 
00864 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
00865 NS_IMETHODIMP nsWebBrowser::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
00866 {
00867     if (mProgressListener)
00868     {
00869         return mProgressListener->OnSecurityChange(aWebProgress, aRequest, state);
00870     }
00871     return NS_OK;
00872 }
00873 
00874 //*****************************************************************************
00875 // nsWebBrowser::nsIWebBrowserPersist
00876 //*****************************************************************************
00877 
00878 /* attribute unsigned long persistFlags; */
00879 NS_IMETHODIMP nsWebBrowser::GetPersistFlags(PRUint32 *aPersistFlags)
00880 {
00881     NS_ENSURE_ARG_POINTER(aPersistFlags);
00882     nsresult rv = NS_OK;
00883     if (mPersist)
00884     {
00885         rv = mPersist->GetPersistFlags(&mPersistFlags);
00886     }
00887     *aPersistFlags = mPersistFlags;
00888     return rv;
00889 }
00890 NS_IMETHODIMP nsWebBrowser::SetPersistFlags(PRUint32 aPersistFlags)
00891 {
00892     nsresult rv = NS_OK;
00893     mPersistFlags = aPersistFlags;
00894     if (mPersist)
00895     {
00896         rv = SetPersistFlags(mPersistFlags);
00897         mPersist->GetPersistFlags(&mPersistFlags);
00898     }
00899     return rv;
00900 }
00901 
00902 
00903 /* readonly attribute unsigned long currentState; */
00904 NS_IMETHODIMP nsWebBrowser::GetCurrentState(PRUint32 *aCurrentState)
00905 {
00906     NS_ENSURE_ARG_POINTER(aCurrentState);
00907     if (mPersist)
00908     {
00909         mPersist->GetCurrentState(&mPersistCurrentState);
00910     }
00911     *aCurrentState = mPersistCurrentState;
00912     return NS_OK;
00913 }
00914 
00915 /* readonly attribute unsigned long result; */
00916 NS_IMETHODIMP nsWebBrowser::GetResult(PRUint32 *aResult)
00917 {
00918     NS_ENSURE_ARG_POINTER(aResult);
00919     if (mPersist)
00920     {
00921         mPersist->GetResult(&mPersistResult);
00922     }
00923     *aResult = mPersistResult;
00924     return NS_OK;
00925 }
00926 
00927 /* attribute nsIWebBrowserPersistProgress progressListener; */
00928 NS_IMETHODIMP nsWebBrowser::GetProgressListener(nsIWebProgressListener * *aProgressListener)
00929 {
00930     NS_ENSURE_ARG_POINTER(aProgressListener);
00931     *aProgressListener = mProgressListener;
00932     NS_IF_ADDREF(*aProgressListener);
00933     return NS_OK;
00934 }
00935   
00936 NS_IMETHODIMP nsWebBrowser::SetProgressListener(nsIWebProgressListener * aProgressListener)
00937 {
00938     mProgressListener = aProgressListener;
00939     return NS_OK;
00940 }
00941 
00942 /* void saveURI (in nsIURI aURI, in nsIURI aReferrer,
00943    in nsISupports aCacheKey, in nsIInputStream aPostData, in wstring aExtraHeaders,
00944    in nsISupports aFile); */
00945 NS_IMETHODIMP nsWebBrowser::SaveURI(
00946     nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData,
00947     const char *aExtraHeaders, nsISupports *aFile)
00948 {
00949     if (mPersist)
00950     {
00951         PRUint32 currentState;
00952         mPersist->GetCurrentState(&currentState);
00953         if (currentState == PERSIST_STATE_FINISHED)
00954         {
00955             mPersist = nsnull;
00956         }
00957         else
00958         {
00959             // You can't save again until the last save has completed
00960             return NS_ERROR_FAILURE;
00961         }
00962     }
00963 
00964     nsCOMPtr<nsIURI> uri;
00965     if (aURI)
00966     {
00967         uri = aURI;
00968     }
00969     else
00970     {
00971         nsresult rv = GetCurrentURI(getter_AddRefs(uri));
00972         if (NS_FAILED(rv))
00973         {
00974             return NS_ERROR_FAILURE;
00975         }
00976     }
00977 
00978     // Create a throwaway persistence object to do the work
00979     nsresult rv;
00980     mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
00981     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
00982     mPersist->SetProgressListener(this);
00983     mPersist->SetPersistFlags(mPersistFlags);
00984     mPersist->GetCurrentState(&mPersistCurrentState);
00985     rv = mPersist->SaveURI(uri, aCacheKey, aReferrer, aPostData, aExtraHeaders, aFile);
00986     if (NS_FAILED(rv))
00987     {
00988         mPersist = nsnull;
00989     }
00990     return rv;
00991 }
00992 
00993 /* void saveChannel (in nsIChannel aChannel, in nsISupports aFile); */
00994 NS_IMETHODIMP nsWebBrowser::SaveChannel(
00995     nsIChannel* aChannel, nsISupports *aFile)
00996 {
00997     if (mPersist)
00998     {
00999         PRUint32 currentState;
01000         mPersist->GetCurrentState(&currentState);
01001         if (currentState == PERSIST_STATE_FINISHED)
01002         {
01003             mPersist = nsnull;
01004         }
01005         else
01006         {
01007             // You can't save again until the last save has completed
01008             return NS_ERROR_FAILURE;
01009         }
01010     }
01011 
01012     // Create a throwaway persistence object to do the work
01013     nsresult rv;
01014     mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
01015     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
01016     mPersist->SetProgressListener(this);
01017     mPersist->SetPersistFlags(mPersistFlags);
01018     mPersist->GetCurrentState(&mPersistCurrentState);
01019     rv = mPersist->SaveChannel(aChannel, aFile);
01020     if (NS_FAILED(rv))
01021     {
01022         mPersist = nsnull;
01023     }
01024     return rv;
01025 }
01026 
01027 /* void saveDocument (in nsIDOMDocument document, in nsISupports aFile, in nsISupports aDataPath); */
01028 NS_IMETHODIMP nsWebBrowser::SaveDocument(
01029     nsIDOMDocument *aDocument, nsISupports *aFile, nsISupports *aDataPath,
01030     const char *aOutputContentType, PRUint32 aEncodingFlags, PRUint32 aWrapColumn)
01031 {
01032     if (mPersist)
01033     {
01034         PRUint32 currentState;
01035         mPersist->GetCurrentState(&currentState);
01036         if (currentState == PERSIST_STATE_FINISHED)
01037         {
01038             mPersist = nsnull;
01039         }
01040         else
01041         {
01042             // You can't save again until the last save has completed
01043             return NS_ERROR_FAILURE;
01044         }
01045     }
01046 
01047     // Use the specified DOM document, or if none is specified, the one
01048     // attached to the web browser.
01049 
01050     nsCOMPtr<nsIDOMDocument> doc;
01051     if (aDocument)
01052     {
01053         doc = do_QueryInterface(aDocument);
01054     }
01055     else
01056     {
01057         GetDocument(getter_AddRefs(doc));
01058     }
01059     if (!doc)
01060     {
01061         return NS_ERROR_FAILURE;
01062     }
01063 
01064     // Create a throwaway persistence object to do the work
01065     nsresult rv;
01066     mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
01067     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
01068     mPersist->SetProgressListener(this);
01069     mPersist->SetPersistFlags(mPersistFlags);
01070     mPersist->GetCurrentState(&mPersistCurrentState);
01071     rv = mPersist->SaveDocument(doc, aFile, aDataPath, aOutputContentType, aEncodingFlags, aWrapColumn);
01072     if (NS_FAILED(rv))
01073     {
01074         mPersist = nsnull;
01075     }
01076     return rv;
01077 }
01078 
01079 /* void cancelSave(); */
01080 NS_IMETHODIMP nsWebBrowser::CancelSave()
01081 {
01082     if (mPersist)
01083     {
01084         return mPersist->CancelSave();
01085     }
01086     return NS_OK;
01087 }
01088 
01089 /* void cancel(nsresult aReason); */
01090 NS_IMETHODIMP nsWebBrowser::Cancel(nsresult aReason)
01091 {
01092     if (mPersist)
01093     {
01094         return mPersist->Cancel(aReason);
01095     }
01096     return NS_OK;
01097 }
01098 
01099 
01100 
01101 
01102 //*****************************************************************************
01103 // nsWebBrowser::nsIBaseWindow
01104 //*****************************************************************************
01105 
01106 NS_IMETHODIMP nsWebBrowser::InitWindow(nativeWindow aParentNativeWindow,
01107    nsIWidget* aParentWidget, PRInt32 aX, PRInt32 aY, PRInt32 aCX, PRInt32 aCY)   
01108 {
01109    NS_ENSURE_ARG(aParentNativeWindow || aParentWidget);
01110    NS_ENSURE_STATE(!mDocShell || mInitInfo);
01111 
01112    if(aParentWidget)
01113       NS_ENSURE_SUCCESS(SetParentWidget(aParentWidget), NS_ERROR_FAILURE);
01114    else
01115       NS_ENSURE_SUCCESS(SetParentNativeWindow(aParentNativeWindow),
01116          NS_ERROR_FAILURE);
01117 
01118    NS_ENSURE_SUCCESS(SetPositionAndSize(aX, aY, aCX, aCY, PR_FALSE),
01119       NS_ERROR_FAILURE);
01120 
01121    return NS_OK;
01122 }
01123 
01124 NS_IMETHODIMP nsWebBrowser::Create()
01125 {
01126    NS_ENSURE_STATE(!mDocShell && (mParentNativeWindow || mParentWidget));
01127 
01128    NS_ENSURE_SUCCESS(EnsureDocShellTreeOwner(), NS_ERROR_FAILURE);
01129 
01130    nsCOMPtr<nsIWidget> docShellParentWidget(mParentWidget);
01131    if(!mParentWidget) // We need to create a widget
01132       {
01133       // Create the widget
01134       NS_ENSURE_TRUE(mInternalWidget = do_CreateInstance(kChildCID), NS_ERROR_FAILURE);
01135 
01136       docShellParentWidget = mInternalWidget;
01137       nsWidgetInitData  widgetInit;
01138 
01139       widgetInit.clipChildren = PR_TRUE;
01140       widgetInit.mContentType = (mContentType == typeChrome || 
01141         mContentType == typeChromeWrapper)? eContentTypeUI: eContentTypeContent;
01142 
01143       widgetInit.mWindowType = eWindowType_child;
01144       nsRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx, mInitInfo->cy);
01145       
01146       mInternalWidget->SetClientData(NS_STATIC_CAST(nsWebBrowser *, this));
01147       mInternalWidget->Create(mParentNativeWindow, bounds, nsWebBrowser::HandleEvent,
01148                               nsnull, nsnull, nsnull, &widgetInit);  
01149       }
01150 
01151    nsCOMPtr<nsIDocShell> docShell(do_CreateInstance("@mozilla.org/webshell;1"));
01152    NS_ENSURE_SUCCESS(SetDocShell(docShell), NS_ERROR_FAILURE);
01153 
01154    // get the system default window background colour
01155    {
01156       nsCOMPtr<nsILookAndFeel> laf = do_GetService(kLookAndFeelCID);
01157       laf->GetColor(nsILookAndFeel::eColor_WindowBackground, mBackgroundColor);
01158    }
01159 
01160    // the docshell has been set so we now have our listener registrars.
01161    if (mListenerArray) {
01162       // we had queued up some listeners, let's register them now.
01163       PRInt32 count = mListenerArray->Count();
01164       PRInt32 i = 0;
01165       NS_ASSERTION(count > 0, "array construction problem");
01166       while (i < count) {
01167           nsWebBrowserListenerState *state = (nsWebBrowserListenerState*)mListenerArray->ElementAt(i);
01168           NS_ASSERTION(state, "array construction problem");
01169           nsCOMPtr<nsISupports> listener = do_QueryReferent(state->mWeakPtr);
01170           NS_ASSERTION(listener, "bad listener");
01171           (void)BindListener(listener, state->mID);
01172           i++;
01173       }
01174       (void)mListenerArray->EnumerateForwards(deleteListener, nsnull);
01175       NS_DELETEXPCOM(mListenerArray);
01176       mListenerArray = nsnull;
01177    }
01178 
01179    // HACK ALERT - this registration registers the nsDocShellTreeOwner as a 
01180    // nsIWebBrowserListener so it can setup it's MouseListener in one of the 
01181    // progress callbacks. If we can register the MouseListener another way, this 
01182    // registration can go away, and nsDocShellTreeOwner can stop implementing
01183    // nsIWebProgressListener.
01184    nsCOMPtr<nsISupports> supports = nsnull;
01185    (void)mDocShellTreeOwner->QueryInterface(NS_GET_IID(nsIWebProgressListener),
01186                              NS_STATIC_CAST(void**, getter_AddRefs(supports)));
01187    (void)BindListener(supports, NS_GET_IID(nsIWebProgressListener));
01188 
01189    NS_ENSURE_SUCCESS(mDocShellAsWin->InitWindow(nsnull,
01190       docShellParentWidget, mInitInfo->x, mInitInfo->y, mInitInfo->cx,
01191       mInitInfo->cy), NS_ERROR_FAILURE);
01192 
01193    mDocShellAsItem->SetName(mInitInfo->name.get());
01194    if (mContentType == typeChromeWrapper)
01195    {
01196        mDocShellAsItem->SetItemType(nsIDocShellTreeItem::typeChrome);
01197    }
01198    else
01199    {
01200        mDocShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent);
01201    }
01202    mDocShellAsItem->SetTreeOwner(mDocShellTreeOwner);
01203    
01204    // If the webbrowser is a content docshell item then we won't hear any
01205    // events from subframes. To solve that we install our own chrome event handler
01206    // that always gets called (even for subframes) for any bubbling event.
01207 
01208    if(!mInitInfo->sessionHistory)
01209       mInitInfo->sessionHistory = do_CreateInstance(NS_SHISTORY_CONTRACTID);
01210    NS_ENSURE_TRUE(mInitInfo->sessionHistory, NS_ERROR_FAILURE);
01211    mDocShellAsNav->SetSessionHistory(mInitInfo->sessionHistory);
01212    
01213    // Hook up global history. Do not fail if we can't - just assert.
01214    nsresult rv = EnableGlobalHistory(PR_TRUE);
01215    NS_ASSERTION(NS_SUCCEEDED(rv), "EnableGlobalHistory() failed");
01216 
01217    NS_ENSURE_SUCCESS(mDocShellAsWin->Create(), NS_ERROR_FAILURE);
01218 
01219    // Hook into the OnSecurirtyChange() notification for lock/unlock icon
01220    // updates
01221    nsCOMPtr<nsIDOMWindow> domWindow;
01222    rv = GetContentDOMWindow(getter_AddRefs(domWindow));
01223    if (NS_SUCCEEDED(rv))
01224    {
01225        // this works because the implementation of nsISecureBrowserUI
01226        // (nsSecureBrowserUIImpl) get a docShell from the domWindow,
01227        // and calls docShell->SetSecurityUI(this);
01228        nsCOMPtr<nsISecureBrowserUI> securityUI =
01229            do_CreateInstance(NS_SECURE_BROWSER_UI_CONTRACTID, &rv);
01230        if (NS_SUCCEEDED(rv)) securityUI->Init(domWindow);
01231    }
01232 
01233    mDocShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0)
01234    mDocShellTreeOwner->AddChromeListeners();
01235 
01236    delete mInitInfo;
01237    mInitInfo = nsnull;
01238 
01239    return NS_OK; 
01240 }
01241 
01242 NS_IMETHODIMP nsWebBrowser::Destroy()
01243 {
01244    InternalDestroy();
01245 
01246    if(!mInitInfo)
01247       mInitInfo = new nsWebBrowserInitInfo();
01248 
01249    return NS_OK;
01250 }
01251 
01252 NS_IMETHODIMP nsWebBrowser::SetPosition(PRInt32 aX, PRInt32 aY)
01253 {
01254    PRInt32 cx = 0;
01255    PRInt32 cy = 0;
01256 
01257    GetSize(&cx, &cy);
01258 
01259    return SetPositionAndSize(aX, aY, cx, cy, PR_FALSE);
01260 }
01261 
01262 NS_IMETHODIMP nsWebBrowser::GetPosition(PRInt32* aX, PRInt32* aY)
01263 {
01264    return GetPositionAndSize(aX, aY, nsnull, nsnull);
01265 }
01266 
01267 NS_IMETHODIMP nsWebBrowser::SetSize(PRInt32 aCX, PRInt32 aCY, PRBool aRepaint)
01268 {
01269    PRInt32 x = 0;
01270    PRInt32 y = 0;
01271 
01272    GetPosition(&x, &y);
01273 
01274    return SetPositionAndSize(x, y, aCX, aCY, aRepaint);
01275 }
01276 
01277 NS_IMETHODIMP nsWebBrowser::GetSize(PRInt32* aCX, PRInt32* aCY)
01278 {
01279    return GetPositionAndSize(nsnull, nsnull, aCX, aCY);
01280 }
01281 
01282 NS_IMETHODIMP nsWebBrowser::SetPositionAndSize(PRInt32 aX, PRInt32 aY,
01283    PRInt32 aCX, PRInt32 aCY, PRBool aRepaint)
01284 {
01285    if(!mDocShell)
01286       {
01287       mInitInfo->x = aX;
01288       mInitInfo->y = aY;
01289       mInitInfo->cx = aCX;
01290       mInitInfo->cy = aCY;
01291       }
01292    else
01293       {
01294       PRInt32 doc_x = aX;
01295       PRInt32 doc_y = aY;
01296 
01297       // If there is an internal widget we need to make the docShell coordinates
01298       // relative to the internal widget rather than the calling app's parent.
01299       // We also need to resize our widget then.
01300       if(mInternalWidget)
01301          {
01302          doc_x = doc_y = 0;
01303          NS_ENSURE_SUCCESS(mInternalWidget->Resize(aX, aY, aCX, aCY, aRepaint),
01304             NS_ERROR_FAILURE);
01305          }
01306       // Now reposition/ resize the doc
01307       NS_ENSURE_SUCCESS(mDocShellAsWin->SetPositionAndSize(doc_x, doc_y, aCX, aCY, 
01308          aRepaint), NS_ERROR_FAILURE);
01309       }
01310 
01311    return NS_OK;
01312 }
01313 
01314 NS_IMETHODIMP nsWebBrowser::GetPositionAndSize(PRInt32* aX, PRInt32* aY, 
01315    PRInt32* aCX, PRInt32* aCY)
01316 {
01317    if(!mDocShell)
01318       {
01319       if(aX)
01320          *aX = mInitInfo->x;
01321       if(aY)
01322          *aY = mInitInfo->y;
01323       if(aCX)
01324          *aCX = mInitInfo->cx;
01325       if(aCY)
01326          *aCY = mInitInfo->cy;
01327       }
01328    else
01329       {
01330       if(mInternalWidget)
01331          {
01332          nsRect bounds;
01333          NS_ENSURE_SUCCESS(mInternalWidget->GetBounds(bounds), NS_ERROR_FAILURE);
01334 
01335          if(aX)
01336             *aX = bounds.x;
01337          if(aY)
01338             *aY = bounds.y;
01339          if(aCX)
01340             *aCX = bounds.width;
01341          if(aCY)
01342             *aCY = bounds.height;
01343          return NS_OK;
01344          }
01345       else
01346          return mDocShellAsWin->GetPositionAndSize(aX, aY, aCX, aCY); // Can directly return this as it is the
01347       }
01348    return NS_OK;
01349 }
01350 
01351 NS_IMETHODIMP nsWebBrowser::Repaint(PRBool aForce)
01352 {
01353    NS_ENSURE_STATE(mDocShell);
01354    return mDocShellAsWin->Repaint(aForce); // Can directly return this as it is the
01355 }                                     // same interface, thus same returns.
01356 
01357 NS_IMETHODIMP nsWebBrowser::GetParentWidget(nsIWidget** aParentWidget)
01358 {
01359    NS_ENSURE_ARG_POINTER(aParentWidget);
01360 
01361    *aParentWidget = mParentWidget;
01362 
01363    NS_IF_ADDREF(*aParentWidget);
01364 
01365    return NS_OK;
01366 }
01367 
01368 NS_IMETHODIMP nsWebBrowser::SetParentWidget(nsIWidget* aParentWidget)
01369 {
01370    NS_ENSURE_STATE(!mDocShell);
01371 
01372    mParentWidget = aParentWidget;
01373    if(mParentWidget)
01374       mParentNativeWindow = mParentWidget->GetNativeData(NS_NATIVE_WIDGET);
01375    else
01376       mParentNativeWindow = nsnull;
01377 
01378    return NS_OK;
01379 }
01380 
01381 NS_IMETHODIMP nsWebBrowser::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
01382 {
01383    NS_ENSURE_ARG_POINTER(aParentNativeWindow);
01384    
01385    *aParentNativeWindow = mParentNativeWindow;
01386 
01387    return NS_OK;
01388 }
01389 
01390 NS_IMETHODIMP nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWindow)
01391 {
01392    NS_ENSURE_STATE(!mDocShell);
01393    
01394 #if (defined(XP_MAC) || defined(XP_MACOSX)) && !defined(MOZ_WIDGET_COCOA)
01395    nsresult rv = EnsureTopLevelWidget(aParentNativeWindow);
01396    NS_ENSURE_SUCCESS(rv, rv);
01397    mParentNativeWindow = mTopLevelWidget->GetNativeData(NS_NATIVE_WINDOW);
01398 #else
01399    mParentNativeWindow = aParentNativeWindow;
01400 #endif
01401 
01402    return NS_OK;
01403 }
01404 
01405 NS_IMETHODIMP nsWebBrowser::GetVisibility(PRBool* visibility)
01406 {
01407    NS_ENSURE_ARG_POINTER(visibility);
01408 
01409    if(!mDocShell)
01410       *visibility = mInitInfo->visible;
01411    else
01412       NS_ENSURE_SUCCESS(mDocShellAsWin->GetVisibility(visibility), NS_ERROR_FAILURE);
01413 
01414    return NS_OK;
01415 }
01416 
01417 NS_IMETHODIMP nsWebBrowser::SetVisibility(PRBool aVisibility)
01418 {
01419    if(!mDocShell)
01420       mInitInfo->visible = aVisibility;
01421    else
01422       {
01423       NS_ENSURE_SUCCESS(mDocShellAsWin->SetVisibility(aVisibility), NS_ERROR_FAILURE);
01424       if(mInternalWidget)
01425          mInternalWidget->Show(aVisibility);
01426       }
01427 
01428    return NS_OK;
01429 }
01430 
01431 NS_IMETHODIMP nsWebBrowser::GetEnabled(PRBool *aEnabled)
01432 {
01433   if (mInternalWidget)
01434     return mInternalWidget->IsEnabled(aEnabled);
01435   return NS_ERROR_FAILURE;
01436 }
01437 
01438 NS_IMETHODIMP nsWebBrowser::SetEnabled(PRBool aEnabled)
01439 {
01440   if (mInternalWidget)
01441     return mInternalWidget->Enable(aEnabled);
01442   return NS_ERROR_FAILURE;
01443 }
01444 
01445 NS_IMETHODIMP
01446 nsWebBrowser::GetBlurSuppression(PRBool *aBlurSuppression)
01447 {
01448   NS_ENSURE_ARG_POINTER(aBlurSuppression);
01449   *aBlurSuppression = PR_FALSE;
01450   return NS_ERROR_NOT_IMPLEMENTED;
01451 }
01452 
01453 NS_IMETHODIMP
01454 nsWebBrowser::SetBlurSuppression(PRBool aBlurSuppression)
01455 {
01456   return NS_ERROR_NOT_IMPLEMENTED;
01457 }
01458 
01459 NS_IMETHODIMP nsWebBrowser::GetMainWidget(nsIWidget** mainWidget)
01460 {
01461    NS_ENSURE_ARG_POINTER(mainWidget);
01462 
01463    if(mInternalWidget)
01464       *mainWidget = mInternalWidget;
01465    else
01466       *mainWidget = mParentWidget;
01467 
01468    NS_IF_ADDREF(*mainWidget);
01469 
01470    return NS_OK;
01471 }
01472 
01473 NS_IMETHODIMP nsWebBrowser::SetFocus()
01474 {
01475    NS_ENSURE_STATE(mDocShell);
01476 
01477    if (NS_FAILED(mDocShellAsWin->SetFocus()))
01478      return NS_ERROR_FAILURE;
01479 
01480    return NS_OK;
01481 }
01482 
01483 NS_IMETHODIMP nsWebBrowser::GetTitle(PRUnichar** aTitle)
01484 {
01485    NS_ENSURE_ARG_POINTER(aTitle);
01486    NS_ENSURE_STATE(mDocShell);
01487 
01488    NS_ENSURE_SUCCESS(mDocShellAsWin->GetTitle(aTitle), NS_ERROR_FAILURE);
01489 
01490    return NS_OK;
01491 }
01492 
01493 NS_IMETHODIMP nsWebBrowser::SetTitle(const PRUnichar* aTitle)
01494 {
01495    NS_ENSURE_STATE(mDocShell);
01496 
01497    NS_ENSURE_SUCCESS(mDocShellAsWin->SetTitle(aTitle), NS_ERROR_FAILURE);
01498 
01499    return NS_OK;
01500 }
01501 
01502 //*****************************************************************************
01503 // nsWebBrowser::nsIScrollable
01504 //*****************************************************************************
01505 
01506 NS_IMETHODIMP nsWebBrowser::GetCurScrollPos(PRInt32 aScrollOrientation, 
01507    PRInt32* aCurPos)
01508 {
01509    NS_ENSURE_STATE(mDocShell);
01510 
01511    return mDocShellAsScrollable->GetCurScrollPos(aScrollOrientation, aCurPos);
01512 }
01513 
01514 NS_IMETHODIMP nsWebBrowser::SetCurScrollPos(PRInt32 aScrollOrientation, 
01515    PRInt32 aCurPos)
01516 {
01517    NS_ENSURE_STATE(mDocShell);
01518 
01519    return mDocShellAsScrollable->SetCurScrollPos(aScrollOrientation, aCurPos);
01520 }
01521 
01522 NS_IMETHODIMP nsWebBrowser::SetCurScrollPosEx(PRInt32 aCurHorizontalPos, 
01523    PRInt32 aCurVerticalPos)
01524 {
01525    NS_ENSURE_STATE(mDocShell);
01526 
01527    return mDocShellAsScrollable->SetCurScrollPosEx(aCurHorizontalPos, 
01528       aCurVerticalPos);
01529 }
01530 
01531 NS_IMETHODIMP nsWebBrowser::GetScrollRange(PRInt32 aScrollOrientation,
01532    PRInt32* aMinPos, PRInt32* aMaxPos)
01533 {
01534    NS_ENSURE_STATE(mDocShell);
01535 
01536    return mDocShellAsScrollable->GetScrollRange(aScrollOrientation, aMinPos,
01537       aMaxPos);
01538 }
01539 
01540 NS_IMETHODIMP nsWebBrowser::SetScrollRange(PRInt32 aScrollOrientation,
01541    PRInt32 aMinPos, PRInt32 aMaxPos)
01542 {
01543    NS_ENSURE_STATE(mDocShell);
01544 
01545    return mDocShellAsScrollable->SetScrollRange(aScrollOrientation, aMinPos,
01546       aMaxPos);
01547 }
01548 
01549 NS_IMETHODIMP nsWebBrowser::SetScrollRangeEx(PRInt32 aMinHorizontalPos,
01550    PRInt32 aMaxHorizontalPos, PRInt32 aMinVerticalPos, PRInt32 aMaxVerticalPos)
01551 {
01552    NS_ENSURE_STATE(mDocShell);
01553 
01554    return mDocShellAsScrollable->SetScrollRangeEx(aMinHorizontalPos,
01555       aMaxHorizontalPos, aMinVerticalPos, aMaxVerticalPos);
01556 }
01557 
01558 NS_IMETHODIMP nsWebBrowser::GetDefaultScrollbarPreferences(PRInt32 aScrollOrientation,
01559    PRInt32* aScrollbarPref)
01560 {
01561    NS_ENSURE_STATE(mDocShell);
01562 
01563    return mDocShellAsScrollable->GetDefaultScrollbarPreferences(aScrollOrientation,
01564       aScrollbarPref);
01565 }
01566 
01567 NS_IMETHODIMP nsWebBrowser::SetDefaultScrollbarPreferences(PRInt32 aScrollOrientation,
01568    PRInt32 aScrollbarPref)
01569 {
01570    NS_ENSURE_STATE(mDocShell);
01571 
01572    return mDocShellAsScrollable->SetDefaultScrollbarPreferences(aScrollOrientation,
01573       aScrollbarPref);
01574 }
01575 
01576 NS_IMETHODIMP nsWebBrowser::GetScrollbarVisibility(PRBool* aVerticalVisible,
01577    PRBool* aHorizontalVisible)
01578 {
01579    NS_ENSURE_STATE(mDocShell);
01580 
01581    return mDocShellAsScrollable->GetScrollbarVisibility(aVerticalVisible,
01582       aHorizontalVisible);
01583 }
01584 
01585 //*****************************************************************************
01586 // nsWebBrowser::nsITextScroll
01587 //*****************************************************************************   
01588 
01589 NS_IMETHODIMP nsWebBrowser::ScrollByLines(PRInt32 aNumLines)
01590 {
01591    NS_ENSURE_STATE(mDocShell);
01592 
01593    return mDocShellAsTextScroll->ScrollByLines(aNumLines);
01594 }
01595 
01596 NS_IMETHODIMP nsWebBrowser::ScrollByPages(PRInt32 aNumPages)
01597 {
01598    NS_ENSURE_STATE(mDocShell);
01599 
01600    return mDocShellAsTextScroll->ScrollByPages(aNumPages);
01601 }
01602 
01603 
01604 //*****************************************************************************
01605 // nsWebBrowser: Listener Helpers
01606 //*****************************************************************************   
01607 
01608 NS_IMETHODIMP nsWebBrowser::SetDocShell(nsIDocShell* aDocShell)
01609 {
01610      if(aDocShell)
01611      {
01612          NS_ENSURE_TRUE(!mDocShell, NS_ERROR_FAILURE);
01613  
01614          nsCOMPtr<nsIInterfaceRequestor> req(do_QueryInterface(aDocShell));
01615          nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(aDocShell));
01616          nsCOMPtr<nsIDocShellTreeItem> item(do_QueryInterface(aDocShell));
01617          nsCOMPtr<nsIWebNavigation> nav(do_QueryInterface(aDocShell));
01618          nsCOMPtr<nsIScrollable> scrollable(do_QueryInterface(aDocShell));
01619          nsCOMPtr<nsITextScroll> textScroll(do_QueryInterface(aDocShell));
01620          nsCOMPtr<nsIWebProgress> progress(do_GetInterface(aDocShell));
01621          NS_ENSURE_TRUE(req && baseWin && item && nav && scrollable && textScroll && progress,
01622              NS_ERROR_FAILURE);
01623  
01624          mDocShell = aDocShell;
01625          mDocShellAsReq = req;
01626          mDocShellAsWin = baseWin;
01627          mDocShellAsItem = item;
01628          mDocShellAsNav = nav;
01629          mDocShellAsScrollable = scrollable;
01630          mDocShellAsTextScroll = textScroll;
01631          mWebProgress = progress;
01632      }
01633      else
01634      {
01635          if (mDocShellTreeOwner)
01636            mDocShellTreeOwner->RemoveFromWatcher(); // evil twin of Add in Create()
01637          if (mDocShellAsWin)
01638            mDocShellAsWin->Destroy();
01639 
01640          mDocShell = nsnull;
01641          mDocShellAsReq = nsnull;
01642          mDocShellAsWin = nsnull;
01643          mDocShellAsItem = nsnull;
01644          mDocShellAsNav = nsnull;
01645          mDocShellAsScrollable = nsnull;
01646          mDocShellAsTextScroll = nsnull;
01647          mWebProgress = nsnull;
01648      }
01649 
01650      return NS_OK; 
01651 }
01652 
01653 NS_IMETHODIMP nsWebBrowser::EnsureDocShellTreeOwner()
01654 {
01655    if(mDocShellTreeOwner)
01656       return NS_OK;
01657 
01658    mDocShellTreeOwner = new nsDocShellTreeOwner();
01659    NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_OUT_OF_MEMORY);
01660 
01661    NS_ADDREF(mDocShellTreeOwner);
01662    mDocShellTreeOwner->WebBrowser(this);
01663    
01664    return NS_OK;
01665 }
01666 
01667 /* static */
01668 nsEventStatus PR_CALLBACK nsWebBrowser::HandleEvent(nsGUIEvent *aEvent)
01669 {
01670   nsEventStatus  result = nsEventStatus_eIgnore;
01671   nsWebBrowser  *browser = nsnull;
01672   void          *data = nsnull;
01673 
01674   if (!aEvent->widget)
01675     return result;
01676 
01677   aEvent->widget->GetClientData(data);
01678   if (!data)
01679     return result;
01680 
01681   browser = NS_STATIC_CAST(nsWebBrowser *, data);
01682 
01683   switch(aEvent->message) {
01684 
01685   case NS_PAINT: {
01686       nsPaintEvent *paintEvent = NS_STATIC_CAST(nsPaintEvent *, aEvent);
01687       nsIRenderingContext *rc = paintEvent->renderingContext;
01688       nscolor oldColor;
01689       rc->GetColor(oldColor);
01690       rc->SetColor(browser->mBackgroundColor);
01691 
01692       nsIRegion *region = paintEvent->region;
01693       if (region) {
01694           nsRegionRectSet *rects = nsnull;
01695           region->GetRects(&rects);
01696           if (rects) {
01697               for (PRUint32 i = 0; i < rects->mNumRects; ++i) {
01698                   nsRect r(rects->mRects[i].x, rects->mRects[i].y,
01699                            rects->mRects[i].width, rects->mRects[i].height);
01700                   rc->FillRect(r);
01701               }
01702 
01703               region->FreeRects(rects);
01704           }
01705       } else if (paintEvent->rect) {
01706           rc->FillRect(*paintEvent->rect);
01707       }
01708       rc->SetColor(oldColor);
01709       break;
01710     }
01711 
01712   default:
01713     break;
01714   }
01715 
01716   return result;
01717     
01718   
01719 }
01720 
01721 NS_IMETHODIMP nsWebBrowser::GetPrimaryContentWindow(nsIDOMWindowInternal **aDOMWindow)
01722 {
01723   *aDOMWindow = 0;
01724 
01725   nsCOMPtr<nsIDocShellTreeItem> item;
01726   NS_ENSURE_TRUE(mDocShellTreeOwner, NS_ERROR_FAILURE);
01727   mDocShellTreeOwner->GetPrimaryContentShell(getter_AddRefs(item));
01728   NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
01729 
01730   nsCOMPtr<nsIDocShell> docShell;
01731   docShell = do_QueryInterface(item);
01732   NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
01733   
01734   nsCOMPtr<nsIDOMWindowInternal> domWindow;
01735   domWindow = do_GetInterface(docShell);
01736   NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
01737 
01738   *aDOMWindow = domWindow;
01739   NS_ADDREF(*aDOMWindow);
01740   return NS_OK;
01741   
01742 }
01743 //*****************************************************************************
01744 // nsWebBrowser::nsIWebBrowserFocus
01745 //*****************************************************************************   
01746 
01747 /* void activate (); */
01748 NS_IMETHODIMP nsWebBrowser::Activate(void)
01749 {
01750   // stop infinite recursion from windows with onfocus handlers that
01751   // reactivate the window
01752   if (mActivating)
01753     return NS_OK;
01754 
01755   mActivating = PR_TRUE;
01756 
01757   // try to set focus on the last focused window as stored in the
01758   // focus controller object.
01759   nsCOMPtr<nsIDOMWindow> domWindowExternal;
01760   GetContentDOMWindow(getter_AddRefs(domWindowExternal));
01761   nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(domWindowExternal));
01762   PRBool needToFocus = PR_TRUE;
01763   if (piWin) {
01764     nsIFocusController *focusController = piWin->GetRootFocusController();
01765     if (focusController) {
01766       // Go ahead and mark the focus controller as being active.  We have
01767       // to do this even before the activate message comes in.
01768       focusController->SetActive(PR_TRUE);
01769 
01770       nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
01771       focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
01772       if (focusedWindow) {
01773         needToFocus = PR_FALSE;
01774         focusController->SetSuppressFocus(PR_TRUE, "Activation Suppression");
01775         piWin->Focus(); // This sets focus, but we'll ignore it.  
01776                         // A subsequent activate will cause us to stop suppressing.
01777       }
01778     }
01779   }
01780 
01781   // If there wasn't a focus controller and focused window just set
01782   // focus on the primary content shell.  If that wasn't focused,
01783   // try and just set it on the toplevel DOM window.
01784   if (needToFocus) {
01785     nsCOMPtr<nsIDOMWindowInternal> contentDomWindow;
01786     GetPrimaryContentWindow(getter_AddRefs(contentDomWindow));
01787     if (contentDomWindow)
01788       contentDomWindow->Focus();
01789     else if (piWin)
01790       piWin->Focus();
01791   }
01792 
01793   nsCOMPtr<nsIDOMWindow> win;
01794   GetContentDOMWindow(getter_AddRefs(win));
01795   if (win) {
01796     // tell windowwatcher about the new active window
01797     if (mWWatch)
01798       mWWatch->SetActiveWindow(win);
01799 
01800     /* Activate the window itself. Note that this method can be called during
01801        window creation before the PresShell exists (for ex, Windows apps
01802        responding to WM_ACTIVATE), which case nsGlobalWindow::Activate()
01803        will return early.
01804     */
01805     nsCOMPtr<nsPIDOMWindow> privateDOMWindow = do_QueryInterface(win);
01806     if (privateDOMWindow)
01807       privateDOMWindow->Activate();
01808   }
01809 
01810   mActivating = PR_FALSE;
01811   return NS_OK;
01812 }
01813 
01814 /* void deactivate (); */
01815 NS_IMETHODIMP nsWebBrowser::Deactivate(void)
01816 {
01817   /* At this time we don't clear mWWatch's ActiveWindow; we just allow
01818      the presumed other newly active window to set it when it comes in.
01819      This seems harmless and maybe safer, but we have no real evidence
01820      either way just yet. */
01821 
01822   nsCOMPtr<nsIDOMWindow> domWindow;
01823   GetContentDOMWindow(getter_AddRefs(domWindow));
01824   if (domWindow) {
01825     nsCOMPtr<nsPIDOMWindow> privateDOMWindow = do_QueryInterface(domWindow);
01826     if(privateDOMWindow) {
01827       nsIFocusController *focusController =
01828           privateDOMWindow->GetRootFocusController();
01829       if (focusController)
01830         focusController->SetActive(PR_FALSE);
01831       privateDOMWindow->Deactivate();
01832     }
01833   }
01834 
01835   return NS_OK;
01836 }
01837 
01838 /* void setFocusAtFirstElement (); */
01839 NS_IMETHODIMP nsWebBrowser::SetFocusAtFirstElement(void)
01840 {
01841   return NS_OK;
01842 }
01843 
01844 /* void setFocusAtLastElement (); */
01845 NS_IMETHODIMP nsWebBrowser::SetFocusAtLastElement(void)
01846 {
01847   return NS_OK;
01848 }
01849 
01850 /* attribute nsIDOMWindow focusedWindow; */
01851 NS_IMETHODIMP nsWebBrowser::GetFocusedWindow(nsIDOMWindow * *aFocusedWindow)
01852 {
01853     NS_ENSURE_ARG_POINTER(aFocusedWindow);
01854     *aFocusedWindow = nsnull;
01855 
01856     nsresult rv;
01857     nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
01858 
01859     nsCOMPtr<nsIDOMWindow> domWindowExternal;
01860     rv = GetContentDOMWindow(getter_AddRefs(domWindowExternal));
01861     if (NS_FAILED(rv)) return rv;
01862     nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(domWindowExternal /*domWindow*/, &rv));
01863     if (NS_FAILED(rv)) return rv;
01864     
01865     nsIFocusController *focusController = piWin->GetRootFocusController();
01866     if (focusController)
01867       rv = focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
01868     
01869     *aFocusedWindow = focusedWindow;
01870     NS_IF_ADDREF(*aFocusedWindow);
01871     
01872     return *aFocusedWindow ? NS_OK : NS_ERROR_FAILURE;
01873 }
01874 NS_IMETHODIMP nsWebBrowser::SetFocusedWindow(nsIDOMWindow * aFocusedWindow)
01875 {
01876   return NS_OK;
01877 }
01878 
01879 /* attribute nsIDOMElement focusedElement; */
01880 NS_IMETHODIMP nsWebBrowser::GetFocusedElement(nsIDOMElement * *aFocusedElement)
01881 {
01882   NS_ENSURE_ARG_POINTER(aFocusedElement);
01883   *aFocusedElement = nsnull;
01884   
01885   nsresult rv;
01886   nsCOMPtr<nsIDOMElement> focusedElement;
01887 
01888   nsCOMPtr<nsIDOMWindow> domWindowExternal;
01889   rv = GetContentDOMWindow(getter_AddRefs(domWindowExternal));
01890   if (NS_FAILED(rv)) return rv;
01891   nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(domWindowExternal, &rv));
01892   if (NS_FAILED(rv)) return rv;
01893 
01894   nsIFocusController *focusController = piWin->GetRootFocusController();
01895   if (focusController)
01896   rv = focusController->GetFocusedElement(getter_AddRefs(focusedElement));
01897 
01898   *aFocusedElement = focusedElement;
01899   NS_IF_ADDREF(*aFocusedElement);
01900   return *aFocusedElement ? NS_OK : NS_ERROR_FAILURE;
01901 }
01902 
01903 NS_IMETHODIMP nsWebBrowser::SetFocusedElement(nsIDOMElement * aFocusedElement)
01904 {
01905   return NS_OK;
01906 }
01907 
01908 //*****************************************************************************
01909 // nsWebBrowser::nsIWebBrowserStream
01910 //*****************************************************************************   
01911 
01912 /* void openStream(in nsIURI aBaseURI, in ACString aContentType); */
01913 NS_IMETHODIMP nsWebBrowser::OpenStream(nsIURI *aBaseURI, const nsACString& aContentType)
01914 {
01915   nsresult rv;
01916 
01917   if (!mStream) {
01918     mStream = new nsEmbedStream();
01919     mStreamGuard = do_QueryInterface(mStream);
01920     mStream->InitOwner(this);
01921     rv = mStream->Init();
01922     if (NS_FAILED(rv))
01923       return rv;
01924   }
01925 
01926   return mStream->OpenStream(aBaseURI, aContentType);
01927 }
01928 
01929 /* void appendToStream([const, array, size_is(aLen)] in octet aData,
01930  * in unsigned long aLen); */
01931 NS_IMETHODIMP nsWebBrowser::AppendToStream(const PRUint8 *aData, PRUint32 aLen)
01932 {
01933   if (!mStream)
01934     return NS_ERROR_FAILURE;
01935 
01936   return mStream->AppendToStream(aData, aLen);
01937 }
01938 
01939 /* void closeStream (); */
01940 NS_IMETHODIMP nsWebBrowser::CloseStream()
01941 {
01942   nsresult rv;
01943 
01944   if (!mStream)
01945     return NS_ERROR_FAILURE;
01946   rv = mStream->CloseStream();
01947 
01948   // release
01949   mStream = 0;
01950   mStreamGuard = 0;
01951 
01952   return rv;
01953 }