Back to index

lightning-sunbird  0.9+nobinonly
CBrowserShell.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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  *   Conrad Carlen <ccarlen@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 #ifndef __CBrowserShell__
00041 #include "CBrowserShell.h"
00042 #endif
00043 
00044 #include "nsCWebBrowser.h"
00045 #include "nsIComponentManager.h"
00046 #include "nsRepeater.h"
00047 #include "nsString.h"
00048 #include "nsXPIDLString.h"
00049 #include "nsIWebBrowserChrome.h"
00050 #include "nsIDocShell.h"
00051 #include "nsIDocShellTreeOwner.h"
00052 #include "nsIInterfaceRequestor.h"
00053 #include "nsIInterfaceRequestorUtils.h"
00054 #include "nsIWebProgressListener.h"
00055 #include "nsIServiceManager.h"
00056 #include "nsIClipboardCommands.h"
00057 #include "nsIWalletService.h"
00058 #include "nsIDOMWindow.h"
00059 #include "nsIDOMWindowInternal.h"
00060 #include "nsIDOMDocument.h"
00061 #include "nsIDOMHTMLDocument.h"
00062 #include "nsIDocument.h"
00063 #include "nsIDOMHTMLCollection.h"
00064 #include "nsIDOMHTMLLinkElement.h"
00065 #include "nsIDOMHTMLAnchorElement.h"
00066 #include "nsIDOMHTMLImageElement.h"
00067 #include "nsIDOMNSDocument.h"
00068 #include "nsIDOMLocation.h"
00069 #include "nsIWebBrowserFind.h"
00070 #include "nsIWebBrowserFocus.h"
00071 #include "nsIWebBrowserPersist.h"
00072 #include "nsIURI.h"
00073 #include "nsWeakPtr.h"
00074 #include "nsRect.h"
00075 #include "nsReadableUtils.h"
00076 #include "nsILocalFile.h"
00077 #include "nsILocalFileMac.h"
00078 #include "nsWeakReference.h"
00079 #include "nsIChannel.h"
00080 #include "nsIHistoryEntry.h"
00081 #include "nsISHEntry.h"
00082 #include "nsISHistory.h"
00083 #include "nsIWebBrowserPrint.h"
00084 #include "nsIMacTextInputEventSink.h"
00085 #include "nsCRT.h"
00086 #include "nsNetUtil.h"
00087 #include "gfxIImageFrame.h"
00088 #include "nsIImage.h"
00089 
00090 // Local
00091 #include "ApplIDs.h"
00092 #include "CBrowserMsgDefs.h"
00093 #include "CBrowserChrome.h"
00094 #include "CWebBrowserCMAttachment.h"
00095 #include "UMacUnicode.h"
00096 #include "CHeaderSniffer.h"
00097 #include "UCustomNavServicesDialogs.h"
00098 
00099 // PowerPlant
00100 #include <UModalDialogs.h>
00101 #include <LStream.h>
00102 #include <UNavServicesDialogs.h>
00103 #include <LEditText.h>
00104 #include <LCheckBox.h>
00105 #include <UEventMgr.h>
00106 
00107 // ToolBox
00108 #include <InternetConfig.h>
00109 
00110 const nsCString CBrowserShell::kEmptyCString;
00111 nsCOMPtr<nsIDragHelperService> CBrowserShell::sDragHelper;
00112 
00113 //*****************************************************************************
00114 //***    CBrowserShellProgressListener
00115 //*****************************************************************************
00116 
00117 class CBrowserShellProgressListener : public nsIWebProgressListener,
00118                                       public nsSupportsWeakReference
00119 {
00120   public:
00121                                 CBrowserShellProgressListener(CBrowserShell* itsOwner);
00122                                 
00123     NS_DECL_ISUPPORTS
00124     NS_DECL_NSIWEBPROGRESSLISTENER
00125     
00126     void                        SetOwner(CBrowserShell* itsOwner)
00127                                 { mpOwner = itsOwner; }
00128                                 
00129     PRBool                      GetIsLoading()
00130                                 { return mLoading; }
00131                                 
00132   protected:
00133     virtual                     ~CBrowserShellProgressListener();
00134     
00135   protected:
00136     CBrowserShell               *mpOwner;
00137     PRBool                      mLoading;
00138     PRBool                      mUseRealProgFlag;
00139     PRInt32                     mFinishedRequests, mTotalRequests;                       
00140 };
00141 
00142 NS_IMPL_ISUPPORTS2(CBrowserShellProgressListener, nsIWebProgressListener, nsISupportsWeakReference)
00143 
00144 CBrowserShellProgressListener::CBrowserShellProgressListener(CBrowserShell* itsOwner) :
00145     mpOwner(itsOwner),
00146     mLoading(PR_FALSE), mUseRealProgFlag(PR_FALSE),
00147     mFinishedRequests(0), mTotalRequests(0)
00148 {
00149 }
00150 
00151 CBrowserShellProgressListener::~CBrowserShellProgressListener()
00152 {
00153 }
00154 
00155 NS_IMETHODIMP CBrowserShellProgressListener::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus)
00156 {
00157     NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
00158 
00159     if (aStateFlags & STATE_START)
00160     {
00161         if (aStateFlags & STATE_IS_NETWORK)
00162         {
00163             MsgNetStartInfo startInfo(mpOwner);
00164             mpOwner->BroadcastMessage(msg_OnNetStartChange, &startInfo);            
00165             mLoading = true;
00166             
00167             // Init progress vars
00168             mUseRealProgFlag = false;
00169             mTotalRequests = 0;
00170             mFinishedRequests = 0;
00171         }
00172         if (aStateFlags & STATE_IS_REQUEST)
00173             mTotalRequests++;
00174     }
00175     else if (aStateFlags & STATE_STOP)
00176     {
00177         if (aStateFlags & STATE_IS_REQUEST)
00178         {
00179             mFinishedRequests += 1;
00180         
00181             if (!mUseRealProgFlag)
00182             {
00183                 MsgOnProgressChangeInfo progInfo(mpOwner, mFinishedRequests, mTotalRequests);    
00184                 mpOwner->BroadcastMessage(msg_OnProgressChange, &progInfo);
00185             }
00186         }
00187         if (aStateFlags & STATE_IS_NETWORK)
00188         {
00189             MsgNetStopInfo stopInfo(mpOwner);
00190             mpOwner->BroadcastMessage(msg_OnNetStopChange, &stopInfo);
00191             mLoading = false;
00192         }
00193     }
00194     else if (aStateFlags & STATE_TRANSFERRING)
00195     {
00196 
00197         if (aStateFlags & STATE_IS_DOCUMENT)
00198         {
00199             nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
00200             NS_ENSURE_TRUE(channel, NS_ERROR_FAILURE);
00201             nsCAutoString contentType;
00202             channel->GetContentType(contentType);
00203             if (contentType.EqualsLiteral("text/html"))
00204                 mUseRealProgFlag = true;
00205         }
00206         
00207         if (aStateFlags & STATE_IS_REQUEST)
00208         {
00209             if (!mUseRealProgFlag)
00210             {
00211                 MsgOnProgressChangeInfo progInfo(mpOwner, mFinishedRequests, mTotalRequests);    
00212                 mpOwner->BroadcastMessage(msg_OnProgressChange, &progInfo);
00213             }
00214         }
00215     }
00216     return NS_OK;
00217 }
00218 
00219 NS_IMETHODIMP CBrowserShellProgressListener::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress, PRInt32 aCurTotalProgress, PRInt32 aMaxTotalProgress)
00220 {
00221     NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
00222 
00223     if (!mUseRealProgFlag)
00224         return NS_OK;
00225     
00226     MsgOnProgressChangeInfo progInfo(mpOwner, aCurTotalProgress, aMaxTotalProgress);    
00227     mpOwner->BroadcastMessage(msg_OnProgressChange, &progInfo);
00228     
00229     return NS_OK;
00230 }
00231 
00232 NS_IMETHODIMP CBrowserShellProgressListener::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location)
00233 {
00234     NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
00235     
00236     nsCAutoString spec;
00237     
00238        if (location)
00239               location->GetSpec(spec);
00240               
00241        MsgLocationChangeInfo info(mpOwner, spec.get());
00242     mpOwner->BroadcastMessage(msg_OnLocationChange, &info);
00243     
00244     return NS_OK;
00245 }
00246 
00247 NS_IMETHODIMP CBrowserShellProgressListener::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const PRUnichar *aMessage)
00248 {
00249     NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
00250 
00251     MsgStatusChangeInfo info(mpOwner, aStatus, aMessage);
00252     mpOwner->BroadcastMessage(msg_OnStatusChange, &info);
00253 
00254     return NS_OK;
00255 }
00256 
00257 NS_IMETHODIMP CBrowserShellProgressListener::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 state)
00258 {
00259     NS_ENSURE_TRUE(mpOwner, NS_ERROR_NULL_POINTER);
00260 
00261     MsgSecurityChangeInfo info(mpOwner, state);
00262     mpOwner->BroadcastMessage(msg_OnSecurityChange, &info);
00263     
00264     return NS_OK;
00265 }
00266 
00267 
00268 //*****************************************************************************
00269 //***    CBrowserShell: constructors/destructor
00270 //*****************************************************************************
00271 
00272 CBrowserShell::CBrowserShell() :
00273     LDropArea(GetMacWindow()),
00274     mChromeFlags(nsIWebBrowserChrome::CHROME_DEFAULT), mIsMainContent(true),
00275     mContextMenuFlags(nsIContextMenuListener2::CONTEXT_NONE)
00276 {
00277        nsresult rv = CommonConstruct();
00278        if (rv != NS_OK)
00279           Throw_Err(NS_ERROR_GET_CODE(rv));   // If this fails, there's no reason to live anymore :(
00280 }
00281 
00282 
00283 CBrowserShell::CBrowserShell(const SPaneInfo     &inPaneInfo,
00284                                                   const SViewInfo     &inViewInfo,
00285                                                   const UInt32       inChromeFlags,
00286                                                   const Boolean      inIsMainContent) :
00287     LView(inPaneInfo, inViewInfo), LDropArea(GetMacWindow()),
00288     mChromeFlags(inChromeFlags), mIsMainContent(inIsMainContent),
00289     mContextMenuFlags(nsIContextMenuListener2::CONTEXT_NONE)
00290 {
00291        nsresult rv = CommonConstruct();
00292        if (rv != NS_OK)
00293           Throw_Err(NS_ERROR_GET_CODE(rv));   // If this fails, there's no reason to live anymore :(
00294 }
00295 
00296 
00297 CBrowserShell::CBrowserShell(LStream*     inStream) :
00298        LView(inStream), LDropArea(GetMacWindow()),
00299     mContextMenuFlags(nsIContextMenuListener2::CONTEXT_NONE)
00300 {
00301        *inStream >> mChromeFlags;
00302        *inStream >> mIsMainContent;
00303        
00304        nsresult rv = CommonConstruct();
00305        if (rv != NS_OK)
00306           Throw_Err(NS_ERROR_GET_CODE(rv));   // If this fails, there's no reason to live anymore :(
00307 }
00308 
00309 
00310 CBrowserShell::~CBrowserShell()
00311 {
00312     if (mWebBrowser)
00313         mWebBrowser->SetContainerWindow(nsnull);
00314     
00315     if (mChrome)
00316     {
00317         mChrome->SetBrowserShell(nsnull);
00318         NS_RELEASE(mChrome);
00319     }
00320     if (mProgressListener)
00321     {
00322         mProgressListener->SetOwner(nsnull);
00323         NS_RELEASE(mProgressListener);
00324     }
00325 }
00326 
00327 
00328 NS_IMETHODIMP CBrowserShell::CommonConstruct()
00329 {
00330     nsresult  rv;
00331 
00332     mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &rv);
00333     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
00334 
00335     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
00336     NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE);
00337     mWebBrowserAsBaseWin = baseWin;
00338 
00339     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
00340     NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
00341     mWebBrowserAsWebNav = webNav;
00342     
00343     mChrome = new CBrowserChrome(this, mChromeFlags, mIsMainContent);
00344     NS_ENSURE_TRUE(mChrome, NS_ERROR_FAILURE);
00345     NS_ADDREF(mChrome);
00346     AddListener(mChrome);
00347     mWebBrowser->SetContainerWindow(mChrome);
00348         
00349     mProgressListener = new CBrowserShellProgressListener(this);
00350     NS_ENSURE_TRUE(mProgressListener, NS_ERROR_FAILURE);
00351     NS_ADDREF(mProgressListener);
00352 
00353     return NS_OK;
00354 }
00355 
00356 
00357 //*****************************************************************************
00358 //***    CBrowserShell: LPane overrides
00359 //*****************************************************************************
00360 
00361 void CBrowserShell::FinishCreateSelf()
00362 {
00363        FocusDraw();
00364 
00365        Rect portFrame;
00366        CalcPortFrameRect(portFrame);
00367        nsRect   r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
00368        
00369        nsresult rv;
00370        
00371     mWebBrowserAsBaseWin->InitWindow(GetMacWindow(), nsnull, r.x, r.y, r.width, r.height);
00372     mWebBrowserAsBaseWin->Create();
00373     mEventSink = do_GetInterface(mWebBrowser);
00374     ThrowIfNil_(mEventSink);
00375         
00376     // Hook up our progress listener
00377     nsWeakPtr weakling(do_GetWeakReference((nsIWebProgressListener *)mProgressListener));
00378     rv = mWebBrowser->AddWebBrowserListener(weakling, NS_GET_IID(nsIWebProgressListener));
00379     NS_ASSERTION(NS_SUCCEEDED(rv), "Call to AddWebBrowserListener failed");
00380       
00381     AdjustFrame();   
00382        StartRepeating();
00383 }
00384 
00385 
00386 void CBrowserShell::ResizeFrameBy(SInt16  inWidthDelta,
00387                                             SInt16      inHeightDelta,
00388                                             Boolean     inRefresh)
00389 {
00390        LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
00391        AdjustFrame();
00392 }
00393 
00394 
00395 void CBrowserShell::MoveBy(SInt32  inHorizDelta,
00396                                        SInt32    inVertDelta,
00397                                              Boolean    inRefresh)
00398 {
00399        LView::MoveBy(inHorizDelta, inVertDelta, inRefresh);
00400        AdjustFrame();
00401 }
00402 
00403 
00404 void CBrowserShell::ActivateSelf()
00405 {
00406     EventRecord osEvent;
00407     osEvent.what = activateEvt;
00408     osEvent.modifiers = activeFlag;
00409     PRBool handled = PR_FALSE;
00410     mEventSink->DispatchEvent(&osEvent, &handled);
00411 }
00412 
00413 void CBrowserShell::DeactivateSelf()
00414 {
00415     EventRecord osEvent;
00416     osEvent.what = activateEvt;
00417     osEvent.modifiers = 0;
00418     PRBool handled = PR_FALSE;
00419     mEventSink->DispatchEvent(&osEvent, &handled);
00420 }
00421 
00422 void CBrowserShell::ShowSelf()
00423 {
00424     mWebBrowserAsBaseWin->SetVisibility(PR_TRUE);
00425 }
00426 
00427 
00428 void CBrowserShell::DrawSelf()
00429 {
00430     EventRecord osEvent;
00431     osEvent.what = updateEvt;
00432     PRBool handled = PR_FALSE;
00433     mEventSink->DispatchEvent(&osEvent, &handled);
00434 }
00435 
00436        
00437 void CBrowserShell::ClickSelf(const SMouseDownEvent     &inMouseDown)
00438 {
00439        if (!IsTarget())
00440               SwitchTarget(this);
00441 
00442        FocusDraw();
00443   PRBool handled = PR_FALSE;
00444        mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMouseDown.macEvent), &handled);
00445 }
00446 
00447 
00448 void CBrowserShell::EventMouseUp(const EventRecord      &inMacEvent)
00449 {
00450     FocusDraw();
00451     PRBool handled = PR_FALSE;
00452     mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMacEvent), &handled);
00453     
00454     LEventDispatcher *dispatcher = LEventDispatcher::GetCurrentEventDispatcher();
00455     if (dispatcher)
00456         dispatcher->UpdateMenus();
00457 }
00458 
00459 void CBrowserShell::AdjustMouseSelf(Point                      inPortPt,
00460                                     const EventRecord&  inMacEvent,
00461                                     RgnHandle                  outMouseRgn)
00462 {
00463     Rect cursorRect = { inPortPt.h, inPortPt.v, inPortPt.h + 1, inPortPt.v + 1 };
00464     ::RectRgn(outMouseRgn, &cursorRect);
00465 }
00466 
00467 //*****************************************************************************
00468 //***    CBrowserShell: LCommander overrides
00469 //*****************************************************************************
00470 
00471 void CBrowserShell::BeTarget()
00472 {
00473     nsCOMPtr<nsIWebBrowserFocus>  focus(do_GetInterface(mWebBrowser));
00474     if (focus)
00475         focus->Activate();
00476 }
00477 
00478 void CBrowserShell::DontBeTarget()
00479 {
00480     nsCOMPtr<nsIWebBrowserFocus>  focus(do_GetInterface(mWebBrowser));
00481     if (focus)
00482         focus->Deactivate();
00483 }
00484 
00485 Boolean CBrowserShell::HandleKeyPress(const EventRecord &inKeyEvent)
00486 {
00487        // set the QuickDraw origin
00488        FocusDraw();
00489 
00490        // dispatch the event
00491   PRBool handled = PR_FALSE;
00492        Boolean keyHandled = mEventSink->DispatchEvent(&const_cast<EventRecord&>(inKeyEvent), &handled);
00493 
00494        return keyHandled;
00495 }
00496 
00497 Boolean CBrowserShell::ObeyCommand(PP_PowerPlant::CommandT inCommand, void* ioParam)
00498 {
00499        Boolean              cmdHandled = true;
00500 
00501     nsresult rv;
00502     nsCOMPtr<nsIClipboardCommands> clipCmd;
00503 
00504     switch (inCommand)
00505     {
00506         case cmd_Back:
00507             Back();
00508             break;
00509  
00510         case cmd_Forward:
00511             Forward();
00512             break;
00513             
00514         case cmd_Stop:
00515             Stop();
00516             break;
00517             
00518         case cmd_Reload:
00519             Reload();
00520             break;
00521 
00522         case cmd_SaveAs:
00523             rv = SaveDocument(eSaveFormatHTML);
00524             ThrowIfError_(rv);
00525             break;
00526                         
00527         case cmd_Cut:
00528             rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00529             if (NS_SUCCEEDED(rv))
00530                 clipCmd->CutSelection();
00531             break;
00532 
00533         case cmd_Copy:
00534             rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00535             if (NS_SUCCEEDED(rv))
00536                 clipCmd->CopySelection();
00537             break;
00538 
00539         case cmd_Paste:
00540             rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00541             if (NS_SUCCEEDED(rv))
00542                 clipCmd->Paste();
00543             break;
00544 
00545         case cmd_SelectAll:
00546             rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00547             if (NS_SUCCEEDED(rv))
00548                 clipCmd->SelectAll();
00549             break;
00550 
00551               case cmd_Find:
00552                      Find();
00553                      break;
00554 
00555               case cmd_FindNext:
00556                      FindNext();
00557                      break;
00558 
00559         case cmd_OpenLinkInNewWindow:
00560         case cmd_CopyLinkLocation:
00561             {               
00562                 // Get the URL from the link
00563                 ThrowIfNil_(mContextMenuInfo);
00564                 nsAutoString temp;
00565                 rv = mContextMenuInfo->GetAssociatedLink(temp);
00566                 ThrowIfError_(rv);
00567                 NS_ConvertUTF16toUTF8 urlSpec(temp);
00568 
00569                 if (inCommand == cmd_OpenLinkInNewWindow) {
00570                     nsCAutoString referrer;
00571                     rv = GetFocusedWindowURL(temp);
00572                     if (NS_SUCCEEDED(rv))
00573                         AppendUTF16toUTF8(temp, referrer);
00574                     PostOpenURLEvent(urlSpec, referrer);
00575                 }
00576                 else
00577                     UScrap::SetData(kScrapFlavorTypeText, urlSpec.get(), urlSpec.Length());
00578             }
00579             break;
00580             
00581               case cmd_SaveFormData:
00582             {
00583                 nsCOMPtr<nsIDOMWindow> domWindow;
00584                 nsCOMPtr<nsIDOMWindowInternal> domWindowInternal;
00585 
00586                 nsCOMPtr<nsIWalletService> walletService = 
00587                          do_GetService(NS_WALLETSERVICE_CONTRACTID, &rv);
00588                 ThrowIfError_(rv);
00589                 rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
00590                 ThrowIfError_(rv);
00591                 domWindowInternal = do_QueryInterface(domWindow, &rv);
00592                 ThrowIfError_(rv);
00593                 PRUint32 retval;
00594                 rv = walletService->WALLET_RequestToCapture(domWindowInternal, &retval);
00595             }
00596             break;
00597                 
00598               case cmd_PrefillForm:
00599             {
00600                 nsCOMPtr<nsIDOMWindow> domWindow;
00601                 nsCOMPtr<nsIDOMWindowInternal> domWindowInternal;
00602 
00603                 nsCOMPtr<nsIWalletService> walletService = 
00604                          do_GetService(NS_WALLETSERVICE_CONTRACTID, &rv);
00605                 ThrowIfError_(rv);
00606                 rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
00607                 ThrowIfError_(rv);
00608                 domWindowInternal = do_QueryInterface(domWindow, &rv);
00609                 ThrowIfError_(rv);
00610                 PRBool retval;
00611                 // Don't check the result - A result of NS_ERROR_FAILURE means not to show preview dialog
00612                 rv = walletService->WALLET_Prefill(true, domWindowInternal, &retval);
00613             }
00614             break;
00615 
00616         case cmd_ViewPageSource:
00617             {
00618                 nsCAutoString currentURL;
00619                 rv = GetCurrentURL(currentURL);
00620                 ThrowIfError_(rv);
00621                 currentURL.Insert("view-source:", 0);
00622                 PostOpenURLEvent(currentURL, EmptyCString());
00623             }
00624             break;
00625 
00626         case cmd_SaveLinkTarget:
00627             {
00628                 // Get the URL from the link
00629                 ThrowIfNil_(mContextMenuInfo);
00630                 nsAutoString linkText;
00631                 rv = mContextMenuInfo->GetAssociatedLink(linkText);
00632                 ThrowIfError_(rv);
00633                 
00634                 nsCOMPtr<nsIURI> linkURI;
00635                 rv = NS_NewURI(getter_AddRefs(linkURI), NS_ConvertUCS2toUTF8(linkText));
00636                 ThrowIfError_(rv);
00637 
00638                 SaveLink(linkURI);
00639             }
00640             break;
00641             
00642         case cmd_SaveImage:
00643             {
00644                 ThrowIfNil_(mContextMenuInfo);
00645                 nsCOMPtr<nsIURI> imgURI;
00646                 mContextMenuInfo->GetImageSrc(getter_AddRefs(imgURI));
00647                 ThrowIfNil_(imgURI);
00648                 
00649                 SaveLink(imgURI);
00650             }
00651             break;
00652             
00653         case cmd_ViewImage:
00654         case cmd_CopyImageLocation:
00655             {
00656                 ThrowIfNil_(mContextMenuInfo);
00657                 nsCOMPtr<nsIURI> imgURI;
00658                 mContextMenuInfo->GetImageSrc(getter_AddRefs(imgURI));
00659                 ThrowIfNil_(imgURI);
00660                 nsCAutoString temp; 
00661                 rv = imgURI->GetSpec(temp);
00662                 ThrowIfError_(rv);
00663                 if (inCommand == cmd_ViewImage)
00664                     PostOpenURLEvent(temp, EmptyCString());
00665                 else
00666                     UScrap::SetData(kScrapFlavorTypeText, temp.get(), temp.Length());
00667             }
00668             break;
00669         
00670         case cmd_ViewBackgroundImage:
00671             {
00672                 ThrowIfNil_(mContextMenuInfo);
00673                 nsCOMPtr<nsIURI> uri;
00674                 rv = mContextMenuInfo->GetBackgroundImageSrc(getter_AddRefs(uri));
00675                 ThrowIfNil_(uri);
00676                 nsCAutoString temp;
00677                 rv = uri->GetSpec(temp);
00678                 ThrowIfError_(rv);
00679                 PostOpenURLEvent(temp, EmptyCString());
00680             }
00681             break;
00682         
00683         case cmd_CopyImage:
00684             {
00685                 GetClipboardHandler(getter_AddRefs(clipCmd));
00686                 if (clipCmd)
00687                     clipCmd->CopyImageContents();
00688             }
00689             break;
00690                                         
00691         default:
00692             cmdHandled = LCommander::ObeyCommand(inCommand, ioParam);
00693             break;
00694     }
00695     return cmdHandled;
00696 }
00697 
00698 
00699 void CBrowserShell::FindCommandStatus(PP_PowerPlant::CommandT inCommand,
00700                                        Boolean &outEnabled, Boolean &outUsesMark,
00701                                                 UInt16 &outMark, Str255 outName)
00702 {
00703     nsresult rv;
00704     nsCOMPtr<nsIClipboardCommands> clipCmd;
00705     PRBool haveContent, canDo;
00706     nsCOMPtr<nsIURI> currURI;
00707 
00708     rv = mWebBrowserAsWebNav->GetCurrentURI(getter_AddRefs(currURI));
00709     haveContent = NS_SUCCEEDED(rv) && currURI;
00710     
00711     switch (inCommand)
00712     {
00713         case cmd_Back:
00714             outEnabled = CanGoBack();
00715             break;
00716  
00717         case cmd_Forward:
00718             outEnabled = CanGoForward();
00719             break;
00720             
00721         case cmd_Stop:
00722             outEnabled = IsBusy();
00723             break;
00724             
00725         case cmd_Reload:
00726             outEnabled = haveContent;
00727             break;
00728 
00729         case cmd_SaveAs:
00730             outEnabled = haveContent;
00731             break;
00732             
00733         case cmd_Cut:
00734             if (haveContent) {
00735                 rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00736                 if (NS_SUCCEEDED(rv)) {
00737                     rv = clipCmd->CanCutSelection(&canDo);
00738                     outEnabled = NS_SUCCEEDED(rv) && canDo;
00739                 }
00740             }
00741             break;
00742 
00743         case cmd_Copy:
00744             if (haveContent) {
00745                 rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00746                 if (NS_SUCCEEDED(rv)) {
00747                     rv = clipCmd->CanCopySelection(&canDo);
00748                     outEnabled = NS_SUCCEEDED(rv) && canDo;
00749                 }
00750             }
00751             break;
00752 
00753         case cmd_Paste:
00754             if (haveContent) {
00755                 rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00756                 if (NS_SUCCEEDED(rv)) {
00757                     rv = clipCmd->CanPaste(&canDo);
00758                     outEnabled = NS_SUCCEEDED(rv) && canDo;
00759                 }
00760             }
00761             break;
00762 
00763         case cmd_SelectAll:
00764             outEnabled = haveContent;
00765             break;
00766 
00767               case cmd_Find:
00768                      outEnabled = haveContent;
00769                      break;
00770 
00771               case cmd_FindNext:
00772                      outEnabled = haveContent && CanFindNext();
00773                      break;
00774 
00775         case cmd_OpenLinkInNewWindow:
00776             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_LINK) != 0);
00777             break;
00778             
00779         case cmd_ViewPageSource:
00780             outEnabled = haveContent && ((mChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME) == 0);
00781             break;
00782             
00783         case cmd_ViewImage:
00784             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_IMAGE) != 0);
00785             break;
00786 
00787         case cmd_ViewBackgroundImage:
00788             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_BACKGROUND_IMAGE) != 0);
00789             break;
00790 
00791         case cmd_CopyImage:
00792             if (haveContent) {
00793                 rv = GetClipboardHandler(getter_AddRefs(clipCmd));
00794                 if (NS_SUCCEEDED(rv)) {
00795                     rv = clipCmd->CanCopyImageContents(&canDo);
00796                     outEnabled = NS_SUCCEEDED(rv) && canDo;
00797                 }
00798             }
00799             break;
00800             
00801         case cmd_SaveLinkTarget:
00802             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_LINK) != 0);
00803             break;
00804         
00805         case cmd_SaveImage:
00806             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_IMAGE) != 0);
00807             break;
00808             
00809         case cmd_CopyLinkLocation:
00810             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_LINK) != 0);
00811             break;
00812         
00813         case cmd_CopyImageLocation:
00814             outEnabled = haveContent && mContextMenuInfo && ((mContextMenuFlags & nsIContextMenuListener2::CONTEXT_IMAGE) != 0);
00815             break;
00816         
00817               case cmd_SaveFormData:
00818                   outEnabled = haveContent && HasFormElements();
00819                   break;
00820 
00821               case cmd_PrefillForm:
00822                   outEnabled = haveContent && HasFormElements();
00823                   break;
00824 
00825         default:
00826             LCommander::FindCommandStatus(inCommand, outEnabled,
00827                                                         outUsesMark, outMark, outName);
00828             break;
00829     }
00830 }
00831 
00832 
00833 //*****************************************************************************
00834 //***    CBrowserShell: LPeriodical overrides
00835 //*****************************************************************************
00836 
00837 void CBrowserShell::SpendTime(const EventRecord&        inMacEvent)
00838 {
00839     switch (inMacEvent.what)
00840     {
00841         case nullEvent:
00842             HandleMouseMoved(inMacEvent);
00843             break;
00844         
00845         case osEvt:
00846             {
00847                 // The event sink will not set the cursor if we are in the background - which is right.
00848                 // We have to feed it suspendResumeMessages for it to know
00849 
00850                 unsigned char eventType = ((inMacEvent.message >> 24) & 0x00ff);
00851                 if (eventType == suspendResumeMessage) {
00852                     PRBool handled = PR_FALSE;
00853                     mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMacEvent), &handled);
00854                 }
00855                 else if (eventType == mouseMovedMessage)
00856                     HandleMouseMoved(inMacEvent);
00857             }
00858             break;
00859     }
00860 }
00861 
00862 
00863 //*****************************************************************************
00864 //***    CBrowserShell:
00865 //*****************************************************************************
00866 
00867 void CBrowserShell::AddAttachments()
00868 {
00869     // Only add a context menu attachment for full browser windows -
00870     // not view-source and chrome dialogs.
00871     if ((mChromeFlags & (nsIWebBrowserChrome::CHROME_TOOLBAR |
00872                          nsIWebBrowserChrome::CHROME_STATUSBAR)) != 0)
00873     {
00874         CWebBrowserCMAttachment *cmAttachment = new CWebBrowserCMAttachment(this);
00875         ThrowIfNil_(cmAttachment);
00876         cmAttachment->SetCommandList(mcmd_BrowserShellContextMenuCmds);
00877         AddAttachment(cmAttachment);
00878     }
00879 }
00880 
00881 NS_METHOD CBrowserShell::GetWebBrowser(nsIWebBrowser** aBrowser)
00882 {
00883     NS_ENSURE_ARG_POINTER(aBrowser);
00884 
00885     *aBrowser = mWebBrowser;
00886     NS_IF_ADDREF(*aBrowser);
00887     return NS_OK;
00888 }
00889 
00890 
00891 NS_METHOD CBrowserShell::SetWebBrowser(nsIWebBrowser* aBrowser)
00892 {
00893     NS_ENSURE_ARG(aBrowser);
00894 
00895     FocusDraw();
00896 
00897     mWebBrowser = aBrowser;
00898 
00899     nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mWebBrowser));
00900     NS_ENSURE_TRUE(baseWin, NS_ERROR_FAILURE);
00901     mWebBrowserAsBaseWin = baseWin;
00902 
00903     nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
00904     NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
00905     mWebBrowserAsWebNav = webNav;
00906 
00907     Rect portFrame;
00908     CalcPortFrameRect(portFrame);
00909     nsRect   r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
00910        
00911     mWebBrowserAsBaseWin->InitWindow(GetMacWindow(), nsnull, r.x, r.y, r.width, r.height);
00912     mWebBrowserAsBaseWin->Create();
00913     mEventSink = do_GetInterface(mWebBrowser);
00914     ThrowIfNil_(mEventSink);
00915 
00916     AdjustFrame();   
00917 
00918     return NS_OK;
00919 }
00920 
00921 NS_METHOD CBrowserShell::GetWebBrowserChrome(nsIWebBrowserChrome** aChrome)
00922 {
00923     NS_ENSURE_ARG_POINTER(aChrome);
00924     return mChrome->QueryInterface(NS_GET_IID(nsIWebBrowserChrome), (void **)aChrome);
00925 }
00926 
00927 NS_METHOD CBrowserShell::GetContentViewer(nsIContentViewer** aViewer)
00928 {
00929     nsCOMPtr<nsIDocShell> ourDocShell(do_GetInterface(mWebBrowser));
00930     NS_ENSURE_TRUE(ourDocShell, NS_ERROR_FAILURE);
00931     return ourDocShell->GetContentViewer(aViewer);
00932 }
00933 
00934 NS_METHOD CBrowserShell::GetFocusedWindowURL(nsAString& outURL)
00935 {
00936     nsCOMPtr<nsIWebBrowserFocus> wbf(do_GetInterface(mWebBrowser));
00937     if (!wbf)
00938         return NS_ERROR_FAILURE;
00939     nsCOMPtr<nsIDOMWindow> domWindow;
00940     wbf->GetFocusedWindow(getter_AddRefs(domWindow));
00941     if (!domWindow)
00942         mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
00943     if (!domWindow)
00944         return NS_ERROR_FAILURE;
00945     nsCOMPtr<nsIDOMDocument> domDocument;
00946     domWindow->GetDocument(getter_AddRefs(domDocument));
00947     if (!domDocument)
00948         return NS_ERROR_FAILURE;
00949     nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
00950     if (!nsDoc)
00951         return NS_ERROR_FAILURE;
00952     nsCOMPtr<nsIDOMLocation> location;
00953     nsDoc->GetLocation(getter_AddRefs(location));
00954     if (!location)
00955         return NS_ERROR_FAILURE;
00956     return location->GetHref(outURL);
00957 }
00958 
00959 NS_METHOD CBrowserShell::GetPrintSettings(nsIPrintSettings** aSettings)
00960 {
00961     NS_ENSURE_ARG_POINTER(aSettings);
00962     *aSettings = nsnull;
00963     
00964     if (!mPrintSettings) {
00965         // If we don't have print settings yet, make new ones.
00966         nsCOMPtr<nsIWebBrowserPrint> wbPrint(do_GetInterface(mWebBrowser));
00967         NS_ENSURE_TRUE(wbPrint, NS_ERROR_NO_INTERFACE);
00968         wbPrint->GetGlobalPrintSettings(getter_AddRefs(mPrintSettings));
00969     }
00970     if (mPrintSettings) {
00971         *aSettings = mPrintSettings;
00972         NS_ADDREF(*aSettings);
00973         return NS_OK;
00974     }
00975     return NS_ERROR_FAILURE;
00976 }
00977 
00978 //*****************************************************************************
00979 //***    CBrowserShell: Navigation
00980 //*****************************************************************************
00981 
00982 Boolean CBrowserShell::IsBusy()
00983 {
00984     return mProgressListener->GetIsLoading();
00985 }
00986 
00987 
00988 Boolean CBrowserShell::CanGoBack()
00989 {
00990     PRBool      canDo;
00991     nsresult    rv;
00992 
00993     rv = mWebBrowserAsWebNav->GetCanGoBack(&canDo);
00994     return (NS_SUCCEEDED(rv) && canDo);
00995 }
00996 
00997 
00998 Boolean CBrowserShell::CanGoForward()
00999 {
01000     PRBool      canDo;
01001     nsresult    rv;
01002 
01003     rv = mWebBrowserAsWebNav->GetCanGoForward(&canDo);
01004     return (NS_SUCCEEDED(rv) && canDo);
01005 }
01006 
01007 
01008 NS_METHOD CBrowserShell::Back()
01009 {
01010    nsresult rv;
01011     
01012     if (CanGoBack())
01013       rv = mWebBrowserAsWebNav->GoBack();
01014    else
01015    {
01016       ::SysBeep(5);
01017       rv = NS_ERROR_FAILURE;
01018    }
01019    return rv;
01020 }
01021 
01022 NS_METHOD CBrowserShell::Forward()
01023 {
01024    nsresult rv;
01025 
01026     if (CanGoForward())
01027       rv = mWebBrowserAsWebNav->GoForward();
01028    else
01029    {
01030       ::SysBeep(5);
01031       rv = NS_ERROR_FAILURE;
01032    }
01033    return rv;
01034 }
01035 
01036 NS_METHOD CBrowserShell::Stop()
01037 {
01038    return mWebBrowserAsWebNav->Stop(nsIWebNavigation::STOP_ALL);
01039 }
01040 
01041 NS_METHOD CBrowserShell::Reload()
01042 {
01043     return mWebBrowserAsWebNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
01044 }
01045 
01046 //*****************************************************************************
01047 //***    CBrowserShell: URL Loading
01048 //*****************************************************************************
01049 
01050 
01051 NS_METHOD CBrowserShell::LoadURL(const nsACString& urlText, const nsACString& referrer)
01052 {    
01053     nsCOMPtr<nsIURI> referrerURI;
01054     if (referrer.Length()) {
01055         nsresult rv = NS_NewURI(getter_AddRefs(referrerURI), referrer);
01056         NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to make URI for referrer.");
01057     }
01058     return mWebBrowserAsWebNav->LoadURI(NS_ConvertUTF8toUCS2(urlText).get(),
01059                                         nsIWebNavigation::LOAD_FLAGS_NONE,
01060                                         referrerURI,
01061                                         nsnull,
01062                                         nsnull);
01063 }
01064 
01065 NS_METHOD CBrowserShell::GetCurrentURL(nsACString& urlText)
01066 {
01067     nsresult rv;
01068     nsCOMPtr<nsIURI> currentURI;
01069     rv = mWebBrowserAsWebNav->GetCurrentURI(getter_AddRefs(currentURI));
01070     if (NS_FAILED(rv)) return rv;
01071     rv = currentURI->GetSpec(urlText);
01072     if (NS_FAILED(rv)) return rv;
01073     
01074     return NS_OK;
01075 }
01076 
01077 //*****************************************************************************
01078 //***    CBrowserShell: URI Saving
01079 //*****************************************************************************
01080 
01081 // Save All As from menus
01082 NS_METHOD CBrowserShell::SaveDocument(ESaveFormat inSaveFormat)
01083 {
01084     nsresult    rv;
01085     
01086     nsCOMPtr<nsIDOMDocument> domDocument;
01087     rv = mWebBrowserAsWebNav->GetDocument(getter_AddRefs(domDocument));
01088     if (NS_FAILED(rv)) return rv;
01089 
01090     nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(domDocument));
01091     if (!nsDoc)
01092         return NS_ERROR_FAILURE;
01093     nsCOMPtr<nsIDOMLocation> location;
01094     nsDoc->GetLocation(getter_AddRefs(location));
01095     if (!location)
01096         return NS_ERROR_FAILURE;
01097     
01098     nsAutoString docLocation;
01099     rv = location->GetHref(docLocation);
01100     if (NS_FAILED(rv))
01101       return rv;
01102 
01103     nsCOMPtr<nsIURI> documentURI;
01104     rv = NS_NewURI(getter_AddRefs(documentURI), NS_ConvertUCS2toUTF8(docLocation));
01105     if (NS_FAILED(rv))
01106       return rv;
01107 
01108     return SaveInternal(documentURI, domDocument, EmptyString(), false, inSaveFormat);     // don't bypass cache
01109 }
01110 
01111 // Save link target
01112 NS_METHOD CBrowserShell::SaveLink(nsIURI* inURI)
01113 {
01114     return SaveInternal(inURI, nsnull, EmptyString(), true, eSaveFormatHTML);     // bypass cache
01115 }
01116 
01117 const char* const kPersistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
01118 
01119 NS_METHOD CBrowserShell::SaveInternal(nsIURI* inURI, nsIDOMDocument* inDocument,
01120   const nsAString& inSuggestedFilename, Boolean inBypassCache, ESaveFormat inSaveFormat)
01121 {
01122     nsresult rv;
01123     // Create our web browser persist object.  This is the object that knows
01124     // how to actually perform the saving of the page (and of the images
01125     // on the page).
01126     nsCOMPtr<nsIWebBrowserPersist> webPersist(do_CreateInstance(kPersistContractID, &rv));
01127     if (!webPersist)
01128         return rv;
01129     
01130     // Make a temporary file object that we can save to.
01131     nsCOMPtr<nsIProperties> dirService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
01132     if (!dirService)
01133         return rv;
01134     nsCOMPtr<nsIFile> tmpFile;
01135     dirService->Get("TmpD", NS_GET_IID(nsIFile), getter_AddRefs(tmpFile));
01136     static short unsigned int tmpRandom = 0;
01137     nsAutoString tmpNo; tmpNo.AppendInt(tmpRandom++);
01138     nsAutoString saveFile(NS_LITERAL_STRING("-sav"));
01139     saveFile += tmpNo;
01140     saveFile.Append(NS_LITERAL_STRING("tmp"));
01141     tmpFile->Append(saveFile);
01142     
01143     // Get the post data if we're an HTML doc.
01144     nsCOMPtr<nsIInputStream> postData;
01145     if (inDocument) {
01146       nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mWebBrowser));
01147       nsCOMPtr<nsISHistory> sessionHistory;
01148       webNav->GetSessionHistory(getter_AddRefs(sessionHistory));
01149       nsCOMPtr<nsIHistoryEntry> entry;
01150       PRInt32 sindex;
01151       sessionHistory->GetIndex(&sindex);
01152       sessionHistory->GetEntryAtIndex(sindex, PR_FALSE, getter_AddRefs(entry));
01153       nsCOMPtr<nsISHEntry> shEntry(do_QueryInterface(entry));
01154       if (shEntry)
01155           shEntry->GetPostData(getter_AddRefs(postData));
01156     }
01157 
01158     // when saving, we first fire off a save with a nsHeaderSniffer as a progress
01159     // listener. This allows us to look for the content-disposition header, which
01160     // can supply a filename, and maybe has something to do with CGI-generated
01161     // content (?)
01162     CHeaderSniffer* sniffer = new CHeaderSniffer(webPersist, tmpFile, inURI, inDocument, postData,
01163                                         inSuggestedFilename, inBypassCache, inSaveFormat);
01164     if (!sniffer)
01165         return NS_ERROR_OUT_OF_MEMORY;
01166 
01167     webPersist->SetProgressListener(sniffer);  // owned
01168     
01169     return webPersist->SaveURI(inURI, nsnull, nsnull, nsnull, nsnull, tmpFile);
01170 }
01171 
01172 
01173 //*****************************************************************************
01174 //***    CBrowserShell: Text Searching
01175 //*****************************************************************************
01176 
01177 Boolean CBrowserShell::Find()
01178 {
01179     nsresult rv;
01180     nsXPIDLString stringBuf;
01181     PRBool  findBackwards;
01182     PRBool  wrapFind;
01183     PRBool  entireWord;
01184     PRBool  matchCase;
01185 
01186     nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
01187     if (!finder) return FALSE;
01188     finder->GetSearchString(getter_Copies(stringBuf));
01189     finder->GetFindBackwards(&findBackwards);    
01190     finder->GetWrapFind(&wrapFind);    
01191     finder->GetEntireWord(&entireWord);    
01192     finder->GetMatchCase(&matchCase);    
01193 
01194     Boolean     result = FALSE;
01195     nsString    searchString(stringBuf.get());
01196 
01197     if (DoFindDialog(searchString, findBackwards, wrapFind, entireWord, matchCase))
01198     {
01199         PRBool  didFind;
01200 
01201         finder->SetSearchString(searchString.get());
01202         finder->SetFindBackwards(findBackwards);    
01203         finder->SetWrapFind(wrapFind);    
01204         finder->SetEntireWord(entireWord);    
01205         finder->SetMatchCase(matchCase);    
01206         rv = finder->FindNext(&didFind);
01207         result = (NS_SUCCEEDED(rv) && didFind);
01208         if (!result)
01209           ::SysBeep(1);
01210     }
01211     return result;
01212 }
01213 
01214 Boolean CBrowserShell::Find(const nsAString& searchString,
01215                             Boolean findBackwards,
01216                             Boolean wrapFind,
01217                             Boolean entireWord,
01218                             Boolean matchCase)
01219 {
01220     nsresult    rv;
01221     Boolean     result;
01222     PRBool      didFind;
01223 
01224     nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
01225     if (!finder) return FALSE;
01226 
01227     finder->SetSearchString(PromiseFlatString(searchString).get());
01228     finder->SetFindBackwards(findBackwards);    
01229     finder->SetWrapFind(wrapFind);    
01230     finder->SetEntireWord(entireWord);    
01231     finder->SetMatchCase(matchCase);    
01232 
01233     rv = finder->FindNext(&didFind);
01234     result = (NS_SUCCEEDED(rv) && didFind);
01235     if (!result)
01236         ::SysBeep(1);
01237 
01238     return result;
01239 }
01240 
01241 Boolean CBrowserShell::CanFindNext()
01242 {
01243     nsresult    rv;
01244 
01245     nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
01246     if (!finder) return FALSE;
01247     
01248     nsXPIDLString searchStr;
01249     rv = finder->GetSearchString(getter_Copies(searchStr));
01250     return (NS_SUCCEEDED(rv) && !searchStr.IsEmpty());
01251 }
01252 
01253 
01254 Boolean CBrowserShell::FindNext()
01255 {
01256     nsresult    rv;
01257     Boolean     result;
01258     PRBool      didFind;
01259 
01260     nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(mWebBrowser));
01261     if (!finder) return FALSE;
01262     rv = finder->FindNext(&didFind);
01263     result = (NS_SUCCEEDED(rv) && didFind);
01264     if (!result)
01265         ::SysBeep(1);
01266 
01267     return result;
01268 }
01269 
01270 
01271 NS_IMETHODIMP CBrowserShell::OnShowContextMenu(PRUint32 aContextFlags,
01272                                                nsIContextMenuInfo *aInfo)
01273 {
01274     // Find our CWebBrowserCMAttachment, if any
01275     CWebBrowserCMAttachment *aCMAttachment = nsnull;
01276     const TArray<LAttachment*>* theAttachments = GetAttachmentsList();
01277     
01278     if (theAttachments) {
01279         TArrayIterator<LAttachment*> iterate(*theAttachments);
01280         
01281         LAttachment*    theAttach;
01282         while (iterate.Next(theAttach)) {
01283             aCMAttachment = dynamic_cast<CWebBrowserCMAttachment*>(theAttach);
01284             if (aCMAttachment != nil)
01285                 break;
01286         }
01287     }
01288     if (!aCMAttachment) {
01289         NS_ASSERTION(PR_FALSE, "No CWebBrowserCMAttachment");
01290         return NS_OK;
01291     }
01292                 
01293     EventRecord macEvent;        
01294     UEventMgr::GetMouseAndModifiers(macEvent);
01295     
01296     mContextMenuFlags = aContextFlags;
01297     mContextMenuInfo = aInfo;
01298     aCMAttachment->DoContextMenuClick(macEvent);
01299     mContextMenuFlags = 0;
01300     mContextMenuInfo = nsnull;
01301 
01302     return NS_OK;
01303 }
01304                                           
01305 NS_IMETHODIMP CBrowserShell::OnShowTooltip(PRInt32 aXCoords,
01306                                            PRInt32 aYCoords,
01307                                            const PRUnichar *aTipText)
01308 {
01309     nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
01310     
01311 #if TARGET_CARBON
01312     if ((Ptr)HMDisplayTag != (Ptr)kUnresolvedCFragSymbolAddress &&
01313         (Ptr)HMHideTag != (Ptr)kUnresolvedCFragSymbolAddress)
01314     {
01315         HMHelpContentRec contentRec;
01316         Point location;
01317 
01318         location.h = aXCoords; location.v = aYCoords;
01319         FocusDraw();
01320         LocalToPortPoint(location);
01321         PortToGlobalPoint(location);
01322         
01323         contentRec.version = kMacHelpVersion;
01324         contentRec.absHotRect.top = contentRec.absHotRect.bottom = location.v;
01325         contentRec.absHotRect.left = contentRec.absHotRect.right = location.h;
01326         ::InsetRect(&contentRec.absHotRect, -4, -4);
01327         contentRec.tagSide = kHMOutsideBottomScriptAligned;
01328         contentRec.content[kHMMinimumContentIndex].contentType = kHMCFStringContent;
01329         contentRec.content[kHMMinimumContentIndex].u.tagCFString = 
01330             ::CFStringCreateWithCharactersNoCopy(NULL, (const UniChar *)aTipText, nsCRT::strlen(aTipText), kCFAllocatorNull);
01331         contentRec.content[kHMMaximumContentIndex].contentType = kHMNoContent;
01332         
01333         ::HMDisplayTag(&contentRec);
01334         rv = NS_OK;
01335     }
01336 #endif
01337 
01338     return rv;
01339 }
01340 
01341 NS_IMETHODIMP CBrowserShell::OnHideTooltip()
01342 {
01343     nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
01344     
01345 #if TARGET_CARBON
01346     if ((Ptr)HMHideTag != (Ptr)kUnresolvedCFragSymbolAddress)
01347     {
01348         ::HMHideTag();
01349         rv = NS_OK;
01350     }
01351 #endif
01352 
01353     return rv;
01354 }
01355 
01356 
01357 void CBrowserShell::HandleMouseMoved(const EventRecord& inMacEvent)
01358 {
01359     static Point     lastWhere = {0, 0};
01360 
01361     if (IsActive() && (*(long*)&lastWhere != *(long*)&inMacEvent.where))
01362     {
01363         FocusDraw();
01364         PRBool handled = PR_FALSE;
01365         mEventSink->DispatchEvent(&const_cast<EventRecord&>(inMacEvent), &handled);
01366         lastWhere = inMacEvent.where;
01367     }
01368 }
01369 
01370 
01371 void CBrowserShell::AdjustFrame()
01372 {
01373     FocusDraw();
01374        
01375     Rect portFrame;
01376     CalcPortFrameRect(portFrame);
01377     nsRect r(portFrame.left, portFrame.top, portFrame.right - portFrame.left, portFrame.bottom - portFrame.top);
01378               
01379     mWebBrowserAsBaseWin->SetPositionAndSize(r.x, r.y, r.width, r.height, PR_TRUE);
01380 }
01381 
01382 
01383 Boolean CBrowserShell::DoFindDialog(nsAString& searchText,
01384                                      PRBool& findBackwards,
01385                                      PRBool& wrapFind,
01386                                      PRBool& entireWord,
01387                                      PRBool& caseSensitive)
01388 {
01389     enum
01390     {
01391         kSearchTextEdit       = FOUR_CHAR_CODE('Text'),
01392         kCaseSensitiveCheck   = FOUR_CHAR_CODE('Case'),
01393         kWrapAroundCheck      = FOUR_CHAR_CODE('Wrap'),
01394         kSearchBackwardsCheck = FOUR_CHAR_CODE('Back'),
01395         kEntireWordCheck      = FOUR_CHAR_CODE('Entr')
01396     };
01397 
01398     Boolean     result;
01399 
01400     try
01401     {
01402         // Create stack-based object for handling the dialog box
01403 
01404         StDialogHandler     theHandler(dlog_FindDialog, this);
01405         LWindow                    *theDialog = theHandler.GetDialog();
01406         Str255          aStr;
01407 
01408         // Set initial text for string in dialog box
01409 
01410         CPlatformUCSConversion::GetInstance()->UCSToPlatform(searchText, aStr);
01411 
01412         LEditText    *editField = dynamic_cast<LEditText*>(theDialog->FindPaneByID(kSearchTextEdit));
01413         editField->SetDescriptor(aStr);
01414         theDialog->SetLatentSub(editField);
01415 
01416         LCheckBox   *caseSensCheck, *entireWordCheck, *wrapAroundCheck, *backwardsCheck;
01417 
01418         caseSensCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kCaseSensitiveCheck));
01419         ThrowIfNot_(caseSensCheck);
01420         caseSensCheck->SetValue(caseSensitive ? 1 : 0);
01421         entireWordCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kEntireWordCheck));
01422         ThrowIfNot_(entireWordCheck);
01423         entireWordCheck->SetValue(entireWord ? 1 : 0);
01424         wrapAroundCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kWrapAroundCheck));
01425         ThrowIfNot_(wrapAroundCheck);
01426         wrapAroundCheck->SetValue(wrapFind ? 1 : 0);
01427         backwardsCheck = dynamic_cast<LCheckBox*>(theDialog->FindPaneByID(kSearchBackwardsCheck));
01428         ThrowIfNot_(backwardsCheck);
01429         backwardsCheck->SetValue(findBackwards ? 1 : 0);
01430 
01431         theDialog->Show();
01432 
01433         while (true)  // This is our modal dialog event loop
01434         {                          
01435             MessageT hitMessage = theHandler.DoDialog();
01436 
01437             if (hitMessage == msg_Cancel)
01438             {
01439                 result = FALSE;
01440                 break;
01441                      
01442             }
01443             else if (hitMessage == msg_OK)
01444             {
01445                 editField->GetDescriptor(aStr);
01446                 CPlatformUCSConversion::GetInstance()->PlatformToUCS(aStr, searchText);
01447 
01448                 caseSensitive = caseSensCheck->GetValue() ? TRUE : FALSE;
01449                 entireWord = entireWordCheck->GetValue() ? TRUE : FALSE;
01450                 wrapFind = wrapAroundCheck->GetValue() ? TRUE : FALSE;
01451                 findBackwards = backwardsCheck->GetValue() ? TRUE : FALSE;
01452 
01453                 result = TRUE;
01454                 break;
01455             }
01456         }
01457     }
01458        catch (...)
01459        {
01460           result = FALSE;
01461           // Don't propagate the error.
01462        }
01463        
01464        return result;
01465 }
01466 
01467 nsresult CBrowserShell::GetClipboardHandler(nsIClipboardCommands **aCommand)
01468 {
01469     NS_ENSURE_ARG_POINTER(aCommand);
01470 
01471     nsCOMPtr<nsIClipboardCommands> clipCmd(do_GetInterface(mWebBrowser));
01472     NS_ENSURE_TRUE(clipCmd, NS_ERROR_FAILURE);
01473 
01474     *aCommand = clipCmd;
01475     NS_ADDREF(*aCommand);
01476     return NS_OK;
01477 }
01478 
01479 Boolean CBrowserShell::HasFormElements()
01480 {
01481     nsresult rv;
01482     
01483     nsCOMPtr<nsIDOMWindow> domWindow;
01484     rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
01485     if (NS_SUCCEEDED(rv)) {
01486         nsCOMPtr<nsIDOMDocument> domDoc;
01487         rv = domWindow->GetDocument(getter_AddRefs(domDoc));
01488         if (NS_SUCCEEDED(rv)) {
01489             nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(domDoc);
01490             if (htmlDoc) {
01491                 nsCOMPtr<nsIDOMHTMLCollection> forms;
01492                 htmlDoc->GetForms(getter_AddRefs(forms));
01493                 if (forms) {
01494                     PRUint32 numForms;
01495                     forms->GetLength(&numForms);
01496                     return numForms > 0;
01497                 }
01498             }
01499         }
01500     }
01501     return false;
01502 }
01503 
01504 void CBrowserShell::PostOpenURLEvent(const nsACString& url, const nsACString& referrer)
01505 {    
01506     // Send an AppleEvent to ourselves to open a new window with the given URL
01507     
01508     // IMPORTANT: We need to make our target address using a ProcessSerialNumber
01509     // from GetCurrentProcess. This will cause our AppleEvent to be handled from
01510     // the event loop. Creating and showing a new window before the context menu
01511     // click is done being processed is fatal. If we make the target address with a
01512     // ProcessSerialNumber in which highLongOfPSN == 0 && lowLongOfPSN == kCurrentProcess,
01513     // the event will be dispatched to us directly and we die.
01514     
01515     OSErr err;
01516     ProcessSerialNumber currProcess;
01517     StAEDescriptor selfAddrDesc;
01518     
01519     err = ::GetCurrentProcess(&currProcess);
01520     ThrowIfOSErr_(err);
01521     err = ::AECreateDesc(typeProcessSerialNumber, (Ptr) &currProcess,
01522                          sizeof(currProcess), selfAddrDesc);
01523     ThrowIfOSErr_(err);
01524 
01525     AppleEvent  getURLEvent;
01526     err = ::AECreateAppleEvent(kInternetEventClass, kAEGetURL,
01527                             selfAddrDesc,
01528                             kAutoGenerateReturnID,
01529                             kAnyTransactionID,
01530                             &getURLEvent);
01531     ThrowIfOSErr_(err);
01532 
01533     const nsPromiseFlatCString& flatURL = PromiseFlatCString(url);  
01534     StAEDescriptor urlDesc(typeChar, flatURL.get(), flatURL.Length());
01535     
01536     err = ::AEPutParamDesc(&getURLEvent, keyDirectObject, urlDesc);
01537     if (err) {
01538         ::AEDisposeDesc(&getURLEvent);
01539         Throw_(err);
01540     }
01541     if (referrer.Length() != 0) {
01542         const nsPromiseFlatCString& flatReferrer = PromiseFlatCString(referrer);  
01543         StAEDescriptor referrerDesc(typeChar, flatReferrer.get(), flatReferrer.Length());
01544         err = ::AEPutParamDesc(&getURLEvent, keyGetURLReferrer, referrerDesc);
01545         if (err) {
01546             ::AEDisposeDesc(&getURLEvent);
01547             Throw_(err);
01548         }
01549     }
01550     UAppleEventsMgr::SendAppleEvent(getURLEvent);
01551 }
01552 
01553 
01554 void
01555 CBrowserShell::InsideDropArea(DragReference inDragRef)
01556 {
01557   if ( sDragHelper ) {
01558     PRBool dropAllowed = PR_FALSE;
01559     sDragHelper->Tracking ( inDragRef, mEventSink, &dropAllowed );
01560   }
01561 }
01562 
01563 
01564 void
01565 CBrowserShell::EnterDropArea( DragReference inDragRef, Boolean inDragHasLeftSender)
01566 {
01567   sDragHelper = do_GetService ( "@mozilla.org/widget/draghelperservice;1" );
01568   NS_ASSERTION ( sDragHelper, "Couldn't get a drag service, we're in biiig trouble" );
01569   if ( sDragHelper )
01570     sDragHelper->Enter ( inDragRef, mEventSink );
01571 }
01572 
01573 
01574 void
01575 CBrowserShell::LeaveDropArea( DragReference inDragRef )
01576 {
01577   if ( sDragHelper ) {
01578     sDragHelper->Leave ( inDragRef, mEventSink );
01579     sDragHelper = nsnull;      
01580   }
01581 }
01582 
01583 
01584 Boolean
01585 CBrowserShell::PointInDropArea(Point inGlobalPt)
01586 {
01587   return true;
01588 }
01589 
01590 Boolean
01591 CBrowserShell::DragIsAcceptable( DragReference inDragRef )
01592 {
01593   return true;
01594 }
01595 
01596 void
01597 CBrowserShell::DoDragReceive( DragReference inDragRef )
01598 {
01599   if ( sDragHelper ) {
01600     PRBool dragAccepted = PR_FALSE;
01601     sDragHelper->Drop ( inDragRef, mEventSink, &dragAccepted );
01602   }
01603 }
01604 
01605 #pragma mark -
01606 
01607 OSStatus CBrowserShell::HandleUpdateActiveInputArea(
01608   const nsAString& text, 
01609   PRInt16 script,  
01610   PRInt16 language, 
01611   PRInt32 fixLen, 
01612   const TextRangeArray * hiliteRng
01613 )
01614 {
01615   nsCOMPtr<nsIMacTextInputEventSink> tieSink;
01616   tieSink = do_QueryInterface(mEventSink);
01617   if (!tieSink)
01618     return eventNotHandledErr;
01619     
01620   OSStatus err = noErr;
01621   nsresult res = tieSink->HandleUpdateActiveInputArea( text,
01622                                                        script, language, 
01623                                                        fixLen, (void*)hiliteRng, 
01624                                                        &err);
01625   if (noErr != err)
01626     return err;
01627   if (NS_FAILED(res))
01628     return eventNotHandledErr;
01629   return noErr;
01630 }
01631 
01632 OSStatus CBrowserShell::HandleUnicodeForKeyEvent(
01633   const nsAString& text, 
01634   PRInt16 script,
01635   PRInt16 language, 
01636   const EventRecord * keyboardEvent)
01637 {
01638   nsCOMPtr<nsIMacTextInputEventSink> tieSink;
01639   tieSink = do_QueryInterface(mEventSink);
01640   if (!tieSink)
01641     return eventNotHandledErr;
01642     
01643   OSStatus err = noErr;
01644   nsresult res = tieSink->HandleUnicodeForKeyEvent( text,
01645                                                     script, language, 
01646                                                     (void*)keyboardEvent, 
01647                                                     &err);
01648   if (noErr != err)
01649       return err;
01650   if (NS_FAILED(res))
01651       return eventNotHandledErr;
01652   return noErr;
01653 }
01654 
01655 OSStatus CBrowserShell::HandleOffsetToPos(
01656   PRInt32 offset, 
01657   PRInt16 *pointX, 
01658   PRInt16 *pointY)
01659 {
01660   nsCOMPtr<nsIMacTextInputEventSink> tieSink;
01661   tieSink = do_QueryInterface(mEventSink);
01662   if (!tieSink)
01663     return eventNotHandledErr;
01664     
01665   OSStatus err = noErr;
01666   nsresult res = tieSink->HandleOffsetToPos( offset, pointX, pointY, &err);
01667 
01668   if (noErr != err)
01669       return err;
01670   if (NS_FAILED(res))
01671       return eventNotHandledErr;
01672   return noErr;
01673 }
01674 
01675 OSStatus CBrowserShell::HandlePosToOffset(
01676   PRInt16 currentPointX, 
01677   PRInt16 currentPointY, 
01678   PRInt32 *offset,
01679   PRInt16 *regionClass
01680 )
01681 {
01682   nsCOMPtr<nsIMacTextInputEventSink> tieSink;
01683   tieSink = do_QueryInterface(mEventSink);
01684   if (!tieSink)
01685     return eventNotHandledErr;
01686     
01687   OSStatus err = noErr;
01688   nsresult res = tieSink->HandlePosToOffset( currentPointX, currentPointY, 
01689                                              offset, regionClass, &err);
01690   if (noErr != err)
01691       return err;
01692   if (NS_FAILED(res))
01693       return eventNotHandledErr;
01694   return noErr;
01695 }
01696 
01697 OSStatus CBrowserShell::HandleGetSelectedText(nsAString& selectedText)
01698 {
01699   nsCOMPtr<nsIMacTextInputEventSink> tieSink;
01700   tieSink = do_QueryInterface(mEventSink);
01701   if (!tieSink)
01702     return eventNotHandledErr;
01703     
01704   OSStatus err = noErr;
01705   nsresult res = tieSink->HandleGetSelectedText( selectedText, &err);
01706 
01707   if (noErr != err)
01708       return err;
01709   if (NS_FAILED(res))
01710       return eventNotHandledErr;
01711   return noErr;
01712 }
01713