Back to index

lightning-sunbird  0.9+nobinonly
GeckoContainer.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: Mozilla-sample-code 1.0
00003  *
00004  * Copyright (c) 2002 Netscape Communications Corporation and
00005  * other contributors
00006  *
00007  * Permission is hereby granted, free of charge, to any person obtaining a
00008  * copy of this Mozilla sample software and associated documentation files
00009  * (the "Software"), to deal in the Software without restriction, including
00010  * without limitation the rights to use, copy, modify, merge, publish,
00011  * distribute, sublicense, and/or sell copies of the Software, and to permit
00012  * persons to whom the Software is furnished to do so, subject to the
00013  * following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included
00016  * in all copies or substantial portions of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00021  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00023  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00024  * DEALINGS IN THE SOFTWARE.
00025  *
00026  * Contributor(s):
00027  *   Adam Lock <adamlock@netscape.com>
00028  *
00029  * ***** END LICENSE BLOCK ***** */
00030 
00031 // Mozilla Includes
00032 //#include "nsIGenericFactory.h"
00033 #include "nsIComponentManager.h"
00034 #include "nsXPIDLString.h"
00035 #include "nsIURI.h"
00036 #include "nsIWebProgress.h"
00037 #include "nsIDocShellTreeItem.h"
00038 #include "nsIDOMWindow.h"
00039 #include "nsIDOMWindowInternal.h"
00040 #include "nsIInterfaceRequestor.h"
00041 #include "nsIInterfaceRequestorUtils.h"
00042 #include "nsIURIContentListener.h"
00043 #include "nsCWebBrowser.h"
00044 #include "nsCRT.h"
00045 
00046 #include "GeckoContainer.h"
00047 
00048 
00049 
00050 GeckoContainer::GeckoContainer(GeckoContainerUI *pUI, const char *aRole) :
00051     mUI(pUI),
00052     mNativeWindow(nsnull),
00053     mSizeSet(PR_FALSE),
00054     mIsChromeContainer(PR_FALSE),
00055     mIsURIContentListener(PR_TRUE)
00056 {
00057     NS_ASSERTION(mUI, "No GeckoContainerUI! How do you expect this to work???");
00058     if (aRole)
00059         mRole = aRole;
00060 }
00061 
00062 GeckoContainer::~GeckoContainer()
00063 {
00064     mUI->Destroyed();
00065 }
00066 
00067 nsresult GeckoContainer::CreateBrowser(PRInt32 aX, PRInt32 aY,
00068                                          PRInt32 aCX, PRInt32 aCY, nativeWindow aParent,
00069                                          nsIWebBrowser **aBrowser)
00070 {
00071     NS_ENSURE_ARG_POINTER(aBrowser);
00072     *aBrowser = nsnull;
00073 
00074     nsresult rv;
00075     mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
00076     if (!mWebBrowser || NS_FAILED(rv))
00077         return NS_ERROR_FAILURE;
00078 
00079     mWebBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, this));
00080 
00081     nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(mWebBrowser);
00082     dsti->SetItemType(
00083         mIsChromeContainer ?
00084             nsIDocShellTreeItem::typeChromeWrapper :
00085             nsIDocShellTreeItem::typeContentWrapper);
00086 
00087     nsCOMPtr<nsIBaseWindow> browserBaseWindow = do_QueryInterface(mWebBrowser);
00088 
00089     mNativeWindow = aParent;
00090 
00091     if (!mNativeWindow)
00092         return NS_ERROR_FAILURE;
00093 
00094     browserBaseWindow->InitWindow( mNativeWindow,
00095                              nsnull, 
00096                              aX, aY, aCX, aCY);
00097     browserBaseWindow->Create();
00098 
00099     nsCOMPtr<nsIWebProgressListener> listener(NS_STATIC_CAST(nsIWebProgressListener*, this));
00100     nsCOMPtr<nsIWeakReference> thisListener(do_GetWeakReference(listener));
00101     (void)mWebBrowser->AddWebBrowserListener(thisListener, 
00102         NS_GET_IID(nsIWebProgressListener));
00103 
00104     if (mIsURIContentListener)
00105         mWebBrowser->SetParentURIContentListener(NS_STATIC_CAST(nsIURIContentListener *, this));
00106 
00107 
00108     // The window has been created. Now register for history notifications
00109 //    mWebBrowser->AddWebBrowserListener(thisListener, NS_GET_IID(nsISHistoryListener));
00110 
00111     if (mWebBrowser)
00112     {
00113       *aBrowser = mWebBrowser;
00114       NS_ADDREF(*aBrowser);
00115       return NS_OK;
00116     }
00117     return NS_ERROR_FAILURE;
00118 }
00119 
00120 
00121 void GeckoContainer::ContentFinishedLoading()
00122 {
00123   // if it was a chrome window and no one has already specified a size,
00124   // size to content
00125   if (mWebBrowser && !mSizeSet &&
00126      (mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)) {
00127     nsCOMPtr<nsIDOMWindow> contentWin;
00128     mWebBrowser->GetContentDOMWindow(getter_AddRefs(contentWin));
00129     if (contentWin)
00130         contentWin->SizeToContent();
00131     mUI->ShowWindow(PR_TRUE);
00132   }
00133 }
00134 
00135 //*****************************************************************************
00136 // GeckoContainer::nsISupports
00137 //*****************************************************************************   
00138 
00139 NS_IMPL_ADDREF(GeckoContainer)
00140 NS_IMPL_RELEASE(GeckoContainer)
00141 
00142 NS_INTERFACE_MAP_BEGIN(GeckoContainer)
00143    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
00144    NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
00145    NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
00146    NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
00147    NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
00148    NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow2)
00149    NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) // optional
00150    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
00151    NS_INTERFACE_MAP_ENTRY(nsIObserver)
00152    NS_INTERFACE_MAP_ENTRY(nsIURIContentListener)
00153    NS_INTERFACE_MAP_ENTRY(nsIContextMenuListener2)
00154    NS_INTERFACE_MAP_ENTRY(nsITooltipListener)
00155    NS_INTERFACE_MAP_ENTRY(nsIGeckoContainer)
00156 NS_INTERFACE_MAP_END
00157 
00158 
00159 //*****************************************************************************
00160 // GeckoContainer::nsIGeckoContainer
00161 //*****************************************************************************   
00162 
00163 NS_IMETHODIMP GeckoContainer::GetRole(nsACString &aRole)
00164 {
00165     aRole = mRole;
00166     return NS_OK;
00167 }
00168 
00169 NS_IMETHODIMP GeckoContainer::GetContainerUI(GeckoContainerUI **pUI)
00170 {
00171     *pUI = mUI;
00172     return NS_OK;
00173 }
00174 
00175 //*****************************************************************************
00176 // GeckoContainer::nsIInterfaceRequestor
00177 //*****************************************************************************   
00178 
00179 NS_IMETHODIMP GeckoContainer::GetInterface(const nsIID &aIID, void** aInstancePtr)
00180 {
00181     NS_ENSURE_ARG_POINTER(aInstancePtr);
00182 
00183     *aInstancePtr = 0;
00184     if (aIID.Equals(NS_GET_IID(nsIDOMWindow)))
00185     {
00186         if (mWebBrowser)
00187         {
00188             return mWebBrowser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr);
00189         }
00190         return NS_ERROR_NOT_INITIALIZED;
00191     }
00192     return QueryInterface(aIID, aInstancePtr);
00193 }
00194 
00195 //*****************************************************************************
00196 // GeckoContainer::nsIWebBrowserChrome
00197 //*****************************************************************************   
00198 
00199 NS_IMETHODIMP GeckoContainer::SetStatus(PRUint32 aType, const PRUnichar* aStatus)
00200 {
00201     mUI->UpdateStatusBarText(aStatus);
00202     return NS_OK;
00203 }
00204 
00205 NS_IMETHODIMP GeckoContainer::GetWebBrowser(nsIWebBrowser** aWebBrowser)
00206 {
00207     NS_ENSURE_ARG_POINTER(aWebBrowser);
00208     *aWebBrowser = mWebBrowser;
00209     NS_IF_ADDREF(*aWebBrowser);
00210     return NS_OK;
00211 }
00212 
00213 NS_IMETHODIMP GeckoContainer::SetWebBrowser(nsIWebBrowser* aWebBrowser)
00214 {
00215     mWebBrowser = aWebBrowser;
00216     return NS_OK;
00217 }
00218 
00219 NS_IMETHODIMP GeckoContainer::GetChromeFlags(PRUint32* aChromeMask)
00220 {
00221     *aChromeMask = mChromeFlags;
00222     return NS_OK;
00223 }
00224 
00225 NS_IMETHODIMP GeckoContainer::SetChromeFlags(PRUint32 aChromeMask)
00226 {
00227     mChromeFlags = aChromeMask;
00228     return NS_OK;
00229 }
00230 
00231 NS_IMETHODIMP GeckoContainer::DestroyBrowserWindow(void)
00232 {
00233     mUI->Destroy();
00234     return NS_OK;
00235 }
00236 
00237 
00238 // IN: The desired browser client area dimensions.
00239 NS_IMETHODIMP GeckoContainer::SizeBrowserTo(PRInt32 aWidth, PRInt32 aHeight)
00240 {
00241   /* This isn't exactly correct: we're setting the whole window to
00242      the size requested for the browser. At time of writing, though,
00243      it's fine and useful for winEmbed's purposes. */
00244   mUI->SizeTo(aWidth, aHeight);
00245   mSizeSet = PR_TRUE;
00246   return NS_OK;
00247 }
00248 
00249 
00250 NS_IMETHODIMP GeckoContainer::ShowAsModal(void)
00251 {
00252 /*  if (mDependentParent)
00253     mUI->EnableChromeWindow(mDependentParent, PR_FALSE);
00254 
00255   mContinueModalLoop = PR_TRUE;
00256   mUI->RunEventLoop(mContinueModalLoop);
00257 
00258   if (mDependentParent)
00259     mUI->EnableChromeWindow(mDependentParent, PR_TRUE);
00260 */
00261   return NS_OK;
00262 }
00263 
00264 NS_IMETHODIMP GeckoContainer::IsWindowModal(PRBool *_retval)
00265 {
00266     *_retval = PR_FALSE;
00267     return NS_ERROR_NOT_IMPLEMENTED;
00268 }
00269 
00270 NS_IMETHODIMP GeckoContainer::ExitModalEventLoop(nsresult aStatus)
00271 {
00272   mContinueModalLoop = PR_FALSE;
00273   return NS_OK;
00274 }
00275 
00276 //*****************************************************************************
00277 // GeckoContainer::nsIWebBrowserChromeFocus
00278 //*****************************************************************************
00279 
00280 NS_IMETHODIMP GeckoContainer::FocusNextElement()
00281 {
00282     return NS_ERROR_NOT_IMPLEMENTED;
00283 }
00284 
00285 NS_IMETHODIMP GeckoContainer::FocusPrevElement()
00286 {
00287     return NS_ERROR_NOT_IMPLEMENTED;
00288 }
00289 
00290 //*****************************************************************************
00291 // GeckoContainer::nsIWebProgressListener
00292 //*****************************************************************************   
00293 
00294 NS_IMETHODIMP GeckoContainer::OnProgressChange(nsIWebProgress *progress, nsIRequest *request,
00295                                                   PRInt32 curSelfProgress, PRInt32 maxSelfProgress,
00296                                                   PRInt32 curTotalProgress, PRInt32 maxTotalProgress)
00297 {
00298     mUI->UpdateProgress(curTotalProgress, maxTotalProgress);
00299     return NS_OK;
00300 }
00301 
00302 NS_IMETHODIMP GeckoContainer::OnStateChange(nsIWebProgress *progress, nsIRequest *request,
00303                                                PRUint32 progressStateFlags, nsresult status)
00304 {
00305     if ((progressStateFlags & STATE_START) && (progressStateFlags & STATE_IS_DOCUMENT))
00306     {
00307         mUI->UpdateBusyState(PR_TRUE);
00308     }
00309 
00310     if ((progressStateFlags & STATE_STOP) && (progressStateFlags & STATE_IS_DOCUMENT))
00311     {
00312         mUI->UpdateBusyState(PR_FALSE);
00313         mUI->UpdateProgress(0, 100);
00314         mUI->UpdateStatusBarText(nsnull);
00315         ContentFinishedLoading();
00316     }
00317 
00318     return NS_OK;
00319 }
00320 
00321 
00322 NS_IMETHODIMP GeckoContainer::OnLocationChange(nsIWebProgress* aWebProgress,
00323                                                  nsIRequest* aRequest,
00324                                                  nsIURI *location)
00325 {
00326     PRBool isSubFrameLoad = PR_FALSE; // Is this a subframe load
00327     if (aWebProgress)
00328     {
00329         nsCOMPtr<nsIDOMWindow>  domWindow;
00330         nsCOMPtr<nsIDOMWindow>  topDomWindow;
00331         aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
00332         if (domWindow)
00333         {
00334             // Get root domWindow
00335             domWindow->GetTop(getter_AddRefs(topDomWindow));
00336         }
00337         if (domWindow != topDomWindow)
00338             isSubFrameLoad = PR_TRUE;
00339     }
00340     if (!isSubFrameLoad)
00341         mUI->UpdateCurrentURI();
00342     return NS_OK;
00343 }
00344 
00345 NS_IMETHODIMP 
00346 GeckoContainer::OnStatusChange(nsIWebProgress* aWebProgress,
00347                                  nsIRequest* aRequest,
00348                                  nsresult aStatus,
00349                                  const PRUnichar* aMessage)
00350 {
00351     mUI->UpdateStatusBarText(aMessage);
00352     return NS_OK;
00353 }
00354 
00355 
00356 
00357 NS_IMETHODIMP 
00358 GeckoContainer::OnSecurityChange(nsIWebProgress *aWebProgress, 
00359                                     nsIRequest *aRequest, 
00360                                     PRUint32 state)
00361 {
00362     return NS_OK;
00363 }
00364 
00365 
00366 //*****************************************************************************
00367 // GeckoContainer::nsIEmbeddingSiteWindow
00368 //*****************************************************************************   
00369 
00370 NS_IMETHODIMP GeckoContainer::SetDimensions(PRUint32 aFlags, PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy)
00371 {
00372     return NS_ERROR_NOT_IMPLEMENTED;
00373 }
00374 
00375 NS_IMETHODIMP GeckoContainer::GetDimensions(PRUint32 aFlags, PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy)
00376 {
00377     if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION)
00378     {
00379         *x = 0;
00380         *y = 0;
00381     }
00382     if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER ||
00383         aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER)
00384     {
00385         *cx = 0;
00386         *cy = 0;
00387     }
00388     return NS_ERROR_NOT_IMPLEMENTED;
00389 }
00390 
00391 /* void setFocus (); */
00392 NS_IMETHODIMP GeckoContainer::SetFocus()
00393 {
00394     mUI->SetFocus();
00395     return NS_OK;
00396 }
00397 
00398 /* attribute wstring title; */
00399 NS_IMETHODIMP GeckoContainer::GetTitle(PRUnichar * *aTitle)
00400 {
00401    NS_ENSURE_ARG_POINTER(aTitle);
00402 
00403    *aTitle = nsnull;
00404    
00405    return NS_ERROR_NOT_IMPLEMENTED;
00406 }
00407 NS_IMETHODIMP GeckoContainer::SetTitle(const PRUnichar * aTitle)
00408 {
00409     return NS_ERROR_NOT_IMPLEMENTED;
00410 }
00411 
00412 /* attribute boolean visibility; */
00413 NS_IMETHODIMP GeckoContainer::GetVisibility(PRBool * aVisibility)
00414 {
00415     NS_ENSURE_ARG_POINTER(aVisibility);
00416     *aVisibility = PR_TRUE;
00417     return NS_OK;
00418 }
00419 NS_IMETHODIMP GeckoContainer::SetVisibility(PRBool aVisibility)
00420 {
00421     return NS_OK;
00422 }
00423 
00424 /* attribute nativeSiteWindow siteWindow */
00425 NS_IMETHODIMP GeckoContainer::GetSiteWindow(void * *aSiteWindow)
00426 {
00427    NS_ENSURE_ARG_POINTER(aSiteWindow);
00428 
00429    *aSiteWindow = mNativeWindow;
00430    return NS_OK;
00431 }
00432 
00433 //*****************************************************************************
00434 // GeckoContainer::nsIEmbeddingSiteWindow2
00435 //*****************************************************************************   
00436 
00437 NS_IMETHODIMP GeckoContainer::Blur()
00438 {
00439    mUI->KillFocus();
00440    return NS_OK;
00441 }
00442 
00443 //*****************************************************************************
00444 // GeckoContainer::nsIObserver
00445 //*****************************************************************************   
00446 
00447 NS_IMETHODIMP GeckoContainer::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
00448 {
00449     nsresult rv = NS_OK;
00450     if (nsCRT::strcmp(aTopic, "profile-change-teardown") == 0)
00451     {
00452         // A profile change means death for this window
00453         mUI->Destroy();
00454     }
00455     return rv;
00456 }
00457 
00458 //*****************************************************************************
00459 // GeckoContainer::nsIURIContentListener
00460 //*****************************************************************************   
00461 
00462 /* boolean onStartURIOpen (in nsIURI aURI); */
00463 NS_IMETHODIMP GeckoContainer::OnStartURIOpen(nsIURI *aURI, PRBool *_retval)
00464 {
00465     return NS_ERROR_NOT_IMPLEMENTED;
00466 }
00467 
00468 /* boolean doContent (in string aContentType, in boolean aIsContentPreferred, in nsIRequest aRequest, out nsIStreamListener aContentHandler); */
00469 NS_IMETHODIMP GeckoContainer::DoContent(const char *aContentType, PRBool aIsContentPreferred, nsIRequest *aRequest, nsIStreamListener **aContentHandler, PRBool *_retval)
00470 {
00471     return NS_ERROR_NOT_IMPLEMENTED;
00472 }
00473 
00474 /* boolean isPreferred (in string aContentType, out string aDesiredContentType); */
00475 NS_IMETHODIMP GeckoContainer::IsPreferred(const char *aContentType, char **aDesiredContentType, PRBool *_retval)
00476 {
00477     return NS_ERROR_NOT_IMPLEMENTED;
00478 }
00479 
00480 /* boolean canHandleContent (in string aContentType, in boolean aIsContentPreferred, out string aDesiredContentType); */
00481 NS_IMETHODIMP GeckoContainer::CanHandleContent(const char *aContentType, PRBool aIsContentPreferred, char **aDesiredContentType, PRBool *_retval)
00482 {
00483     return NS_ERROR_NOT_IMPLEMENTED;
00484 }
00485 
00486 /* attribute nsISupports loadCookie; */
00487 NS_IMETHODIMP GeckoContainer::GetLoadCookie(nsISupports * *aLoadCookie)
00488 {
00489     return NS_ERROR_NOT_IMPLEMENTED;
00490 }
00491 NS_IMETHODIMP GeckoContainer::SetLoadCookie(nsISupports * aLoadCookie)
00492 {
00493     return NS_ERROR_NOT_IMPLEMENTED;
00494 }
00495 
00496 /* attribute nsIURIContentListener parentContentListener; */
00497 NS_IMETHODIMP GeckoContainer::GetParentContentListener(nsIURIContentListener * *aParentContentListener)
00498 {
00499     return NS_ERROR_NOT_IMPLEMENTED;
00500 }
00501 NS_IMETHODIMP GeckoContainer::SetParentContentListener(nsIURIContentListener * aParentContentListener)
00502 {
00503     return NS_ERROR_NOT_IMPLEMENTED;
00504 }
00505 
00506 //*****************************************************************************
00507 // GeckoContainer::nsIContextMenuListener2
00508 //*****************************************************************************   
00509 
00510 /* void onShowContextMenu (in unsigned long aContextFlags, in nsIContextMenuInfo aUtils); */
00511 NS_IMETHODIMP GeckoContainer::OnShowContextMenu(PRUint32 aContextFlags, nsIContextMenuInfo *aContextMenuInfo)
00512 {
00513     mUI->ShowContextMenu(aContextFlags, aContextMenuInfo);
00514     return NS_OK;
00515 }
00516 
00517 
00518 //*****************************************************************************
00519 // GeckoContainer::nsITooltipListener
00520 //*****************************************************************************   
00521 
00522 /* void OnShowTooltip (in long aXCoords, in long aYCoords, in wstring aTipText); */
00523 NS_IMETHODIMP GeckoContainer::OnShowTooltip(PRInt32 aXCoords, PRInt32 aYCoords, const PRUnichar *aTipText)
00524 {
00525     mUI->ShowTooltip(aXCoords, aYCoords, aTipText);
00526     return NS_OK;
00527 }
00528 
00529 /* void OnHideTooltip (); */
00530 NS_IMETHODIMP GeckoContainer::OnHideTooltip()
00531 {
00532     mUI->HideTooltip();
00533     return NS_OK;
00534 }