Back to index

lightning-sunbird  0.9+nobinonly
NSBrowserView.mm
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #import "NSBrowserView.h"
00039 #import "nsCocoaBrowserService.h"
00040 
00041 // Embedding includes
00042 #include "nsCWebBrowser.h"
00043 #include "nsIInterfaceRequestor.h"
00044 #include "nsIWebBrowserChrome.h"
00045 #include "nsIEmbeddingSiteWindow.h"
00046 #include "nsIWebProgressListener.h"
00047 #include "nsIWebBrowser.h"
00048 #include "nsIWebNavigation.h"
00049 #include "nsIURI.h"
00050 #include "nsIDOMWindow.h"
00051 #include "nsWeakReference.h"
00052 
00053 // XPCOM and String includes
00054 #include "nsCRT.h"
00055 #include "nsString.h"
00056 #include "nsCOMPtr.h"
00057 
00058 
00059 class nsCocoaBrowserListener : public nsSupportsWeakReference,
00060                                public nsIInterfaceRequestor,
00061                             public nsIWebBrowserChrome,
00062                             public nsIEmbeddingSiteWindow,
00063                                public nsIWebProgressListener
00064 {
00065 public:
00066   nsCocoaBrowserListener(NSBrowserView* aView);
00067   virtual ~nsCocoaBrowserListener();
00068 
00069   NS_DECL_ISUPPORTS
00070   NS_DECL_NSIINTERFACEREQUESTOR
00071   NS_DECL_NSIWEBBROWSERCHROME
00072   NS_DECL_NSIEMBEDDINGSITEWINDOW
00073   NS_DECL_NSIWEBPROGRESSLISTENER
00074 
00075   void AddListener(id <NSBrowserListener> aListener);
00076   void RemoveListener(id <NSBrowserListener> aListener);
00077   void SetContainer(id <NSBrowserContainer> aContainer);
00078 
00079 private:
00080   NSBrowserView* mView;     // WEAK - it owns us
00081   NSMutableArray* mListeners;
00082   id <NSBrowserContainer> mContainer;
00083   PRBool mIsModal;
00084   PRUint32 mChromeFlags;
00085 };
00086 
00087 nsCocoaBrowserListener::nsCocoaBrowserListener(NSBrowserView* aView)
00088   : mView(aView), mContainer(nsnull), mIsModal(PR_FALSE), mChromeFlags(0)
00089 {
00090   mListeners = [[NSMutableArray alloc] init];
00091 }
00092 
00093 nsCocoaBrowserListener::~nsCocoaBrowserListener()
00094 {
00095   [mListeners release];
00096   mView = nsnull;
00097   if (mContainer) {
00098     [mContainer release];
00099   }
00100 }
00101 
00102 NS_IMPL_ISUPPORTS5(nsCocoaBrowserListener,
00103                  nsIInterfaceRequestor,
00104                  nsIWebBrowserChrome,
00105                  nsIEmbeddingSiteWindow,
00106                  nsIWebProgressListener,
00107                  nsISupportsWeakReference)
00108 
00109 // Implementation of nsIInterfaceRequestor
00110 NS_IMETHODIMP 
00111 nsCocoaBrowserListener::GetInterface(const nsIID &aIID, void** aInstancePtr)
00112 {
00113   if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
00114     nsCOMPtr<nsIWebBrowser> browser = dont_AddRef([mView getWebBrowser]);
00115     if (browser)
00116       return browser->GetContentDOMWindow((nsIDOMWindow **) aInstancePtr);
00117   }
00118   
00119   return QueryInterface(aIID, aInstancePtr);
00120 }
00121 
00122 // Implementation of nsIWebBrowserChrome
00123 /* void setStatus (in unsigned long statusType, in wstring status); */
00124 NS_IMETHODIMP 
00125 nsCocoaBrowserListener::SetStatus(PRUint32 statusType, const PRUnichar *status)
00126 {
00127   if (!mContainer) {
00128     return NS_ERROR_FAILURE;
00129   }
00130 
00131   NSString* str = nsnull;
00132   if (status && (*status != PRUnichar(0))) {
00133     str = [NSString stringWithCharacters:status length:nsCRT::strlen(status)];
00134   }
00135 
00136   [mContainer setStatus:str ofType:(NSStatusType)statusType];
00137 
00138   return NS_OK;
00139 }
00140 
00141 /* attribute nsIWebBrowser webBrowser; */
00142 NS_IMETHODIMP 
00143 nsCocoaBrowserListener::GetWebBrowser(nsIWebBrowser * *aWebBrowser)
00144 {
00145   NS_ENSURE_ARG_POINTER(aWebBrowser);
00146   if (!mView) {
00147     return NS_ERROR_FAILURE;
00148   }
00149   *aWebBrowser = [mView getWebBrowser];
00150 
00151   return NS_OK;
00152 }
00153 NS_IMETHODIMP 
00154 nsCocoaBrowserListener::SetWebBrowser(nsIWebBrowser * aWebBrowser)
00155 {
00156   if (!mView) {
00157     return NS_ERROR_FAILURE;
00158   }
00159 
00160   [mView setWebBrowser:aWebBrowser];
00161 
00162   return NS_OK;
00163 }
00164 
00165 /* attribute unsigned long chromeFlags; */
00166 NS_IMETHODIMP 
00167 nsCocoaBrowserListener::GetChromeFlags(PRUint32 *aChromeFlags)
00168 {
00169   NS_ENSURE_ARG_POINTER(aChromeFlags);
00170   *aChromeFlags = mChromeFlags;
00171   return NS_OK;
00172 }
00173 NS_IMETHODIMP 
00174 nsCocoaBrowserListener::SetChromeFlags(PRUint32 aChromeFlags)
00175 {
00176   // XXX Do nothing with them for now
00177   mChromeFlags = aChromeFlags;
00178   return NS_OK;
00179 }
00180 
00181 /* void destroyBrowserWindow (); */
00182 NS_IMETHODIMP 
00183 nsCocoaBrowserListener::DestroyBrowserWindow()
00184 {
00185   // XXX Could send this up to the container, but for now,
00186   // we just destroy the enclosing window.
00187   NSWindow* window = [mView window];
00188 
00189   if (window) {
00190     [window close];
00191   }
00192 
00193   return NS_OK;
00194 }
00195 
00196 /* void sizeBrowserTo (in long aCX, in long aCY); */
00197 NS_IMETHODIMP 
00198 nsCocoaBrowserListener::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY)
00199 {
00200   if (mContainer) {
00201     NSSize size;
00202     
00203     size.width = (float)aCX;
00204     size.height = (float)aCY;
00205 
00206     [mContainer sizeBrowserTo:size];
00207   }
00208   
00209   return NS_OK;
00210 }
00211 
00212 /* void showAsModal (); */
00213 NS_IMETHODIMP 
00214 nsCocoaBrowserListener::ShowAsModal()
00215 {
00216   if (!mView) {
00217     return NS_ERROR_FAILURE;
00218   }
00219 
00220   NSWindow* window = [mView window];
00221 
00222   if (!window) {
00223     return NS_ERROR_FAILURE;
00224   }
00225 
00226   mIsModal = PR_TRUE;
00227   int result = [NSApp runModalForWindow:window];
00228   mIsModal = PR_FALSE;
00229 
00230   return (nsresult)result;
00231 }
00232 
00233 /* boolean isWindowModal (); */
00234 NS_IMETHODIMP 
00235 nsCocoaBrowserListener::IsWindowModal(PRBool *_retval)
00236 {
00237   NS_ENSURE_ARG_POINTER(_retval);
00238 
00239   *_retval = mIsModal;
00240 
00241   return NS_OK;
00242 }
00243 
00244 /* void exitModalEventLoop (in nsresult aStatus); */
00245 NS_IMETHODIMP 
00246 nsCocoaBrowserListener::ExitModalEventLoop(nsresult aStatus)
00247 {
00248   [NSApp stopModalWithCode:(int)aStatus];
00249 
00250   return NS_OK;
00251 }
00252 
00253 // Implementation of nsIEmbeddingSiteWindow
00254 /* void setDimensions (in unsigned long flags, in long x, in long y, in long cx, in long cy); */
00255 NS_IMETHODIMP 
00256 nsCocoaBrowserListener::SetDimensions(PRUint32 flags, 
00257                                   PRInt32 x, 
00258                                   PRInt32 y, 
00259                                   PRInt32 cx, 
00260                                   PRInt32 cy)
00261 {
00262   if (!mView) {
00263     return NS_ERROR_FAILURE;
00264   }
00265 
00266   NSWindow* window = [mView window];
00267   if (!window) {
00268     return NS_ERROR_FAILURE;
00269   }
00270 
00271   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
00272     NSPoint origin;
00273     origin.x = (float)x;
00274     origin.y = (float)y;
00275     [window setFrameOrigin:origin];
00276   }
00277 
00278   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
00279     NSRect frame = [window frame];
00280     frame.size.width = (float)cx;
00281     frame.size.height = (float)cy;
00282     [window setFrame:frame display:YES];
00283   }
00284   else if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER) {
00285     NSSize size;
00286     size.width = (float)cx;
00287     size.height = (float)cy;
00288     [window setContentSize:size];
00289   }
00290 
00291   return NS_OK;
00292 }
00293 
00294 /* void getDimensions (in unsigned long flags, out long x, out long y, out long cx, out long cy); */
00295 NS_IMETHODIMP 
00296 nsCocoaBrowserListener::GetDimensions(PRUint32 flags, 
00297                                   PRInt32 *x, 
00298                                   PRInt32 *y, 
00299                                   PRInt32 *cx, 
00300                                   PRInt32 *cy)
00301 {
00302   NS_ENSURE_ARG_POINTER(x);
00303   NS_ENSURE_ARG_POINTER(y);
00304   NS_ENSURE_ARG_POINTER(cx);
00305   NS_ENSURE_ARG_POINTER(cy);
00306 
00307   if (!mView) {
00308     return NS_ERROR_FAILURE;
00309   }
00310 
00311   NSWindow* window = [mView window];
00312   if (!window) {
00313     return NS_ERROR_FAILURE;
00314   }
00315 
00316   NSRect frame = [window frame];
00317   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
00318     *x = (PRInt32)frame.origin.x;
00319     *y = (PRInt32)frame.origin.y;
00320   }
00321   if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
00322     *cx = (PRInt32)frame.size.width;
00323     *cy = (PRInt32)frame.size.height;
00324   }
00325   else if (flags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER) {
00326     NSView* contentView = [window contentView];
00327     NSRect contentFrame = [contentView frame];
00328     *cx = (PRInt32)contentFrame.size.width;
00329     *cy = (PRInt32)contentFrame.size.height;    
00330   }
00331 
00332   return NS_OK;
00333 }
00334 
00335 /* void setFocus (); */
00336 NS_IMETHODIMP 
00337 nsCocoaBrowserListener::SetFocus()
00338 {
00339   if (!mView) {
00340     return NS_ERROR_FAILURE;
00341   }
00342 
00343   NSWindow* window = [mView window];
00344   if (!window) {
00345     return NS_ERROR_FAILURE;
00346   }
00347 
00348   [window makeKeyAndOrderFront:window];
00349 
00350   return NS_OK;
00351 }
00352 
00353 /* attribute boolean visibility; */
00354 NS_IMETHODIMP 
00355 nsCocoaBrowserListener::GetVisibility(PRBool *aVisibility)
00356 {
00357   NS_ENSURE_ARG_POINTER(aVisibility);
00358 
00359   if (!mView) {
00360     return NS_ERROR_FAILURE;
00361   }
00362 
00363   NSWindow* window = [mView window];
00364   if (!window) {
00365     return NS_ERROR_FAILURE;
00366   }
00367 
00368   *aVisibility = [window isMiniaturized];
00369 
00370   return NS_OK;
00371 }
00372 NS_IMETHODIMP 
00373 nsCocoaBrowserListener::SetVisibility(PRBool aVisibility)
00374 {
00375   if (!mView) {
00376     return NS_ERROR_FAILURE;
00377   }
00378 
00379   NSWindow* window = [mView window];
00380   if (!window) {
00381     return NS_ERROR_FAILURE;
00382   }
00383 
00384   if (aVisibility) {
00385     [window deminiaturize:window];
00386   }
00387   else {
00388     [window miniaturize:window];
00389   }
00390 
00391   return NS_OK;
00392 }
00393 
00394 /* attribute wstring title; */
00395 NS_IMETHODIMP 
00396 nsCocoaBrowserListener::GetTitle(PRUnichar * *aTitle)
00397 {
00398   NS_ENSURE_ARG_POINTER(aTitle);
00399 
00400   if (!mContainer) {
00401     return NS_ERROR_FAILURE;
00402   }
00403 
00404   NSString* title = [mContainer title];
00405   unsigned int length = [title length];
00406   if (length) {
00407     *aTitle = (PRUnichar*)nsMemory::Alloc((length+1)*sizeof(PRUnichar));
00408     if (!*aTitle) {
00409       return NS_ERROR_OUT_OF_MEMORY;
00410     }
00411     [title getCharacters:*aTitle];
00412   }
00413   else {
00414     *aTitle = nsnull;
00415   }
00416   
00417   return NS_OK;
00418 }
00419 NS_IMETHODIMP 
00420 nsCocoaBrowserListener::SetTitle(const PRUnichar * aTitle)
00421 {
00422   NS_ENSURE_ARG(aTitle);
00423 
00424   if (!mContainer) {
00425     return NS_ERROR_FAILURE;
00426   }
00427 
00428   NSString* str = [NSString stringWithCharacters:aTitle length:nsCRT::strlen(aTitle)];
00429   [mContainer setTitle:str];
00430 
00431   return NS_OK;
00432 }
00433 
00434 /* [noscript] readonly attribute voidPtr siteWindow; */
00435 NS_IMETHODIMP 
00436 nsCocoaBrowserListener::GetSiteWindow(void * *aSiteWindow)
00437 {
00438   NS_ENSURE_ARG_POINTER(aSiteWindow);
00439 
00440   if (!mView) {
00441     return NS_ERROR_FAILURE;
00442   }
00443 
00444   NSWindow* window = [mView window];
00445   if (!window) {
00446     return NS_ERROR_FAILURE;
00447   }
00448 
00449   *aSiteWindow = (void*)window;
00450 
00451   return NS_OK;
00452 }
00453 
00454 // Implementation of nsIWebProgressListener
00455 /* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */
00456 NS_IMETHODIMP 
00457 nsCocoaBrowserListener::OnStateChange(nsIWebProgress *aWebProgress, 
00458                                   nsIRequest *aRequest, 
00459                                   PRInt32 aStateFlags, 
00460                                   PRUint32 aStatus)
00461 {
00462   NSEnumerator* enumerator = [mListeners objectEnumerator];
00463   id obj;
00464   
00465   if (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) {
00466     if (aStateFlags & nsIWebProgressListener::STATE_START) {
00467       while ((obj = [enumerator nextObject])) {
00468        [obj onLoadingStarted];
00469       }
00470     }
00471     else if (aStateFlags & nsIWebProgressListener::STATE_STOP) {
00472       while ((obj = [enumerator nextObject])) {
00473        [obj onLoadingCompleted:(NS_SUCCEEDED(aStatus))];
00474       }
00475     }
00476   }
00477 
00478 
00479   return NS_OK;
00480 }
00481 
00482 /* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
00483 NS_IMETHODIMP 
00484 nsCocoaBrowserListener::OnProgressChange(nsIWebProgress *aWebProgress, 
00485                                     nsIRequest *aRequest, 
00486                                     PRInt32 aCurSelfProgress, 
00487                                     PRInt32 aMaxSelfProgress, 
00488                                     PRInt32 aCurTotalProgress, 
00489                                     PRInt32 aMaxTotalProgress)
00490 {
00491   NSEnumerator* enumerator = [mListeners objectEnumerator];
00492   id obj;
00493  
00494   while ((obj = [enumerator nextObject])) {
00495     [obj onProgressChange:aCurTotalProgress outOf:aMaxTotalProgress];
00496   }
00497   
00498   return NS_OK;
00499 }
00500 
00501 /* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */
00502 NS_IMETHODIMP 
00503 nsCocoaBrowserListener::OnLocationChange(nsIWebProgress *aWebProgress, 
00504                                     nsIRequest *aRequest, 
00505                                     nsIURI *location)
00506 {
00507   nsCAutoString spec;
00508   
00509   location->GetAsciiSpec(spec);
00510   if (spec.IsEmpty()) {
00511     return NS_ERROR_FAILURE;
00512   }
00513 
00514   const char* cstr = spec.get();
00515   NSString* str = [NSString stringWithCString:cstr];
00516   NSURL* url = [NSURL URLWithString:str];
00517 
00518   NSEnumerator* enumerator = [mListeners objectEnumerator];
00519   id obj;
00520  
00521   while ((obj = [enumerator nextObject])) {
00522     [obj onLocationChange:url];
00523   }
00524 
00525   return NS_OK;
00526 }
00527 
00528 /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
00529 NS_IMETHODIMP 
00530 nsCocoaBrowserListener::OnStatusChange(nsIWebProgress *aWebProgress, 
00531                                    nsIRequest *aRequest, 
00532                                    nsresult aStatus, 
00533                                    const PRUnichar *aMessage)
00534 {
00535   return NS_OK;
00536 }
00537 
00538 /* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */
00539 NS_IMETHODIMP 
00540 nsCocoaBrowserListener::OnSecurityChange(nsIWebProgress *aWebProgress, 
00541                                     nsIRequest *aRequest, 
00542                                     PRInt32 state)
00543 {
00544   return NS_OK;
00545 }
00546 
00547 void 
00548 nsCocoaBrowserListener::AddListener(id <NSBrowserListener> aListener)
00549 {
00550   [mListeners addObject:aListener];
00551 }
00552 
00553 void 
00554 nsCocoaBrowserListener::RemoveListener(id <NSBrowserListener> aListener)
00555 {
00556   [mListeners removeObject:aListener];
00557 }
00558 
00559 void 
00560 nsCocoaBrowserListener::SetContainer(id <NSBrowserContainer> aContainer)
00561 {
00562   [mContainer autorelease];
00563 
00564   mContainer = aContainer;
00565 
00566   [mContainer retain];
00567 }
00568 
00569 
00570 @implementation NSBrowserView
00571 
00572 - (id)initWithFrame:(NSRect)frame
00573 {
00574   [super initWithFrame:frame];
00575 
00576   nsresult rv = nsCocoaBrowserService::InitEmbedding();
00577   if (NS_FAILED(rv)) {
00578     // XXX need to throw
00579   }
00580   
00581   _listener = new nsCocoaBrowserListener(self);
00582   NS_ADDREF(_listener);
00583 
00584   // Create the web browser instance
00585   nsCOMPtr<nsIWebBrowser> browser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
00586   if (NS_FAILED(rv)) {
00587     // XXX need to throw
00588   }
00589 
00590   _webBrowser = browser;
00591   NS_ADDREF(_webBrowser);
00592 
00593   // Set the container nsIWebBrowserChrome
00594   _webBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, 
00595                                            _listener));
00596   
00597   // Register as a listener for web progress
00598   nsCOMPtr<nsIWeakReference> weak = do_GetWeakReference(NS_STATIC_CAST(nsIWebProgressListener*, _listener));
00599   _webBrowser->AddWebBrowserListener(weak, NS_GET_IID(nsIWebProgressListener));
00600 
00601   // Hook up the widget hierarchy with us as the parent
00602   nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
00603   baseWin->InitWindow((NSView*)self, nsnull, 0, 0, 
00604                     frame.size.width, frame.size.height);
00605   baseWin->Create();
00606 
00607   return self;
00608 }
00609 
00610 - (void)dealloc 
00611 {
00612   NS_RELEASE(_listener);
00613   NS_IF_RELEASE(_webBrowser);
00614   nsCocoaBrowserService::TermEmbedding();
00615 
00616   [super dealloc];
00617 }
00618 
00619 - (void)setFrame:(NSRect)frameRect 
00620 {
00621   [super setFrame:frameRect];
00622   if (_webBrowser) {
00623     nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(_webBrowser);
00624     window->SetSize((PRInt32)frameRect.size.width, 
00625                   (PRInt32)frameRect.size.height,
00626                   PR_TRUE);
00627   }
00628 }
00629 
00630 - (void)addListener:(id <NSBrowserListener>)listener
00631 {
00632   _listener->AddListener(listener);
00633 }
00634 
00635 - (void)removeListener:(id <NSBrowserListener>)listener
00636 {
00637   _listener->RemoveListener(listener);
00638 }
00639 
00640 - (void)setContainer:(id <NSBrowserContainer>)container
00641 {
00642   _listener->SetContainer(container);
00643 }
00644 
00645 - (nsIDOMWindow*)getContentWindow
00646 {
00647   nsIDOMWindow* window;
00648 
00649   _webBrowser->GetContentDOMWindow(&window);
00650 
00651   return window;
00652 }
00653 
00654 - (void)loadURI:(NSURL *)url flags:(unsigned int)flags
00655 {
00656   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00657   
00658   NSString* spec = [url absoluteString];
00659   int length = [spec length];
00660   PRUnichar* specStr = nsMemory::Alloc((length+1) * sizeof(PRUnichar));
00661   [spec getCharacters:specStr];
00662   specStr[length] = PRUnichar(0);
00663   
00664 
00665   PRUint32 navFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
00666   if (flags & NSLoadFlagsDontPutInHistory) {
00667     navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_HISTORY;
00668   }
00669   if (flags & NSLoadFlagsReplaceHistoryEntry) {
00670     navFlags |= nsIWebNavigation::LOAD_FLAGS_REPLACE_HISTORY;
00671   }
00672   if (flags & NSLoadFlagsBypassCacheAndProxy) {
00673     navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | 
00674                 nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
00675   }
00676 
00677   nsresult rv = nav->LoadURI(specStr, navFlags, nsnull, nsnull, nsnull);
00678   if (NS_FAILED(rv)) {
00679     // XXX need to throw
00680   }
00681 
00682   nsMemory::Free(specStr);
00683 }
00684 
00685 - (void)reload:(unsigned int)flags
00686 {
00687   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00688 
00689   PRUint32 navFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
00690   if (flags & NSLoadFlagsBypassCacheAndProxy) {
00691     navFlags |= nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | 
00692                 nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
00693   }
00694 
00695   nsresult rv = nav->Reload(navFlags);
00696   if (NS_FAILED(rv)) {
00697     // XXX need to throw
00698   }  
00699 }
00700 
00701 - (BOOL)canGoBack
00702 {
00703   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00704 
00705   PRBool can;
00706   nav->GetCanGoBack(&can);
00707 
00708   return can ? YES : NO;
00709 }
00710 
00711 - (BOOL)canGoForward
00712 {
00713   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00714 
00715   PRBool can;
00716   nav->GetCanGoForward(&can);
00717 
00718   return can ? YES : NO;
00719 }
00720 
00721 - (void)goBack
00722 {
00723   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00724 
00725   nsresult rv = nav->GoBack();
00726   if (NS_FAILED(rv)) {
00727     // XXX need to throw
00728   }  
00729 }
00730 
00731 - (void)goForward
00732 {
00733   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00734 
00735   nsresult rv = nav->GoForward();
00736   if (NS_FAILED(rv)) {
00737     // XXX need to throw
00738   }  
00739 }
00740 
00741 - (void)gotoIndex:(int)index
00742 {
00743   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00744 
00745   nsresult rv = nav->GotoIndex(index);
00746   if (NS_FAILED(rv)) {
00747     // XXX need to throw
00748   }    
00749 }
00750 
00751 - (void)stop:(unsigned int)flags
00752 {
00753   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00754 
00755   nsresult rv = nav->Stop(flags);
00756   if (NS_FAILED(rv)) {
00757     // XXX need to throw
00758   }    
00759 }
00760 
00761 - (NSURL*)getCurrentURI
00762 {
00763   nsCOMPtr<nsIURI> uri;
00764   nsCOMPtr<nsIWebNavigation> nav = do_QueryInterface(_webBrowser);
00765 
00766   nav->GetCurrentURI(getter_AddRefs(uri));
00767   if (!uri) {
00768     return nsnull;
00769   }
00770 
00771   nsCAutoString spec;
00772   uri->GetAsciiSpec(spec);
00773   
00774   const char* cstr = spec.get();
00775   NSString* str = [NSString stringWithCString:cstr];
00776   NSURL* url = [NSURL URLWithString:str];
00777   
00778   return url;
00779 }
00780 
00781 - (nsIWebBrowser*)getWebBrowser
00782 {
00783   NS_IF_ADDREF(_webBrowser);
00784   return _webBrowser;
00785 }
00786 
00787 - (void)setWebBrowser:(nsIWebBrowser*)browser
00788 {
00789   _webBrowser = browser;
00790 
00791   if (_webBrowser) {
00792     // Set the container nsIWebBrowserChrome
00793     _webBrowser->SetContainerWindow(NS_STATIC_CAST(nsIWebBrowserChrome *, 
00794                                              _listener));
00795 
00796     NSRect frame = [self frame];
00797  
00798     // Hook up the widget hierarchy with us as the parent
00799     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(_webBrowser);
00800     baseWin->InitWindow((NSView*)self, nsnull, 0, 0, 
00801                      frame.size.width, frame.size.height);
00802     baseWin->Create();
00803   }
00804 
00805 }
00806 
00807 @end
00808