home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / central / CURLDispatcher.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  26.7 KB  |  884 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. //    CURLDispatcher.cp
  20.  
  21.  
  22. #include "CURLDispatcher.h"
  23. #include "CNSContext.h"
  24. #include "CBrowserWindow.h"
  25. #include "CDownloadProgressWindow.h"
  26. #include "CWindowMediator.h"
  27. #include "CBrowserContext.h"
  28. #include "CBrowserWindow.h"
  29. #ifdef MOZ_MAIL_NEWS
  30. #include "CMailNewsWindow.h"
  31. #include "CThreadWindow.h"
  32. #include "CMessageWindow.h"
  33. #endif
  34. #include "URobustCreateWindow.h"
  35. #include "uapp.h"
  36. #include "CHTMLClickRecord.h"
  37. #include "CAutoPtr.h"
  38. #include "CAutoPtrXP.h"
  39. #include "cstring.h"
  40.  
  41. #include "xp.h"
  42. #include "macutil.h"
  43. #include "umimemap.h"
  44. #include "ufilemgr.h"
  45. #include "uprefd.h"
  46. #include "xlate.h"
  47. #include "msv2dsk.h"
  48. #include "msgcom.h"
  49. #include "uerrmgr.h"        // Need for GetCString
  50. #include "resgui.h"
  51.  
  52. CBrowserWindow* CURLDispatcher::sLastBrowserWindowCreated = NULL;
  53. CAutoPtr<CURLDispatcher> CURLDispatcher::sDispatcher;
  54. CAutoPtr<CBrowserContext> CURLDispatcher::sDispatchContext;
  55.  
  56. // URL dispatch proc table
  57. // URL types listed in net.h are indices into this table.
  58. // **** NOTE: URL types in net.h start at 1 ****
  59. const Uint32 cNumURLTypes = 39;
  60.  
  61. static DispatchProcPtr dispatchProcs[] =
  62. {
  63.     CURLDispatcher::DispatchToBrowserWindow        // Unknown URL type        0
  64. ,    CURLDispatcher::DispatchToBrowserWindow        // FILE_TYPE_URL           1
  65. ,    CURLDispatcher::DispatchToBrowserWindow        // FTP_TYPE_URL            2
  66. ,    CURLDispatcher::DispatchToBrowserWindow        // GOPHER_TYPE_URL         3
  67. ,    CURLDispatcher::DispatchToBrowserWindow        // HTTP_TYPE_URL           4
  68. ,    CURLDispatcher::DispatchToLibNet            // MAILTO_TYPE_URL         5
  69. //,    CURLDispatcher::DispatchToMailNewsWindow    // NEWS_TYPE_URL           6
  70. ,    CURLDispatcher::DispatchMailboxURL            // NEWS_TYPE_URL           6 (use mailbox code)
  71. ,    NULL        // RLOGIN_TYPE_URL         7
  72. ,    CURLDispatcher::DispatchToBrowserWindow        // TELNET_TYPE_URL         8
  73. ,    CURLDispatcher::DispatchToBrowserWindow        // TN3270_TYPE_URL         9
  74. ,    NULL        // WAIS_TYPE_URL           10
  75. ,    CURLDispatcher::DispatchToBrowserWindow        // ABOUT_TYPE_URL          11
  76. ,    NULL        // FILE_CACHE_TYPE_URL     12
  77. ,    NULL        // MEMORY_CACHE_TYPE_URL   13
  78. ,    CURLDispatcher::DispatchToBrowserWindow        // SECURE_HTTP_TYPE_URL    14
  79. ,    NULL        // INTERNAL_IMAGE_TYPE_URL 15
  80. ,    NULL        // URN_TYPE_URL            16
  81. ,    NULL        // POP3_TYPE_URL           17
  82. ,    CURLDispatcher::DispatchMailboxURL            // MAILBOX_TYPE_URL        18
  83. ,    NULL        // INTERNAL_NEWS_TYPE_URL  19
  84. ,    CURLDispatcher::DispatchToBrowserWindow        // SECURITY_TYPE_URL        20
  85. ,    CURLDispatcher::DispatchToBrowserWindow        // MOCHA_TYPE_URL            21
  86. ,    CURLDispatcher::DispatchToBrowserWindow        // VIEW_SOURCE_TYPE_URL    22
  87. ,    NULL        // HTML_DIALOG_HANDLER_TYPE_URL 23
  88. ,    NULL        // HTML_PANEL_HANDLER_TYPE_URL 24
  89. ,    NULL        // INTERNAL_SECLIB_TYPE_URL 25
  90. ,    NULL        // MSG_SEARCH_TYPE_URL     26
  91. ,    CURLDispatcher::DispatchMailboxURL            // IMAP_TYPE_URL            27
  92. ,    CURLDispatcher::DispatchToLibNet            // LDAP_TYPE_URL            28
  93. ,    NULL        // SECURE_LDAP_TYPE_URL    29
  94. ,    CURLDispatcher::DispatchToBrowserWindow        // WYSIWYG_TYPE_URL        30
  95. ,    CURLDispatcher::DispatchToLibNet            // ADDRESS_BOOK_TYPE_URL    31
  96. ,    NULL        // CLASSID_TYPE_URL        32
  97. ,    NULL        // JAVA_TYPE_URL            33
  98. ,    NULL        // DATA_TYPE_URL            34
  99. ,    CURLDispatcher::DispatchToLibNet        // NETHELP_TYPE_URL        35
  100. ,    NULL        // NFS_TYPE_URL            36
  101. ,    CURLDispatcher::DispatchToBrowserWindow        // MARIMBA_TYPE_URL        37
  102. ,    NULL        // INTERNAL_CERTLDAP_TYPE_URL 38
  103. };
  104.  
  105. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  106. //    Ñ    
  107. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  108.  
  109. CURLDispatcher* CURLDispatcher::GetURLDispatcher()    // singleton class
  110. {
  111.     if (!sDispatcher.get())
  112.     {
  113.         sDispatcher.reset(new CURLDispatcher);
  114.     }
  115.     
  116.     return sDispatcher.get();
  117. }
  118.  
  119. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  120. //    Ñ    
  121. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  122.  
  123. CURLDispatcher::CURLDispatcher()
  124.     :    mDelayedURLs(sizeof(CURLDispatchInfo*))
  125. {
  126. }
  127.  
  128. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  129. //    Ñ    
  130. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  131.  
  132. CURLDispatcher::~CURLDispatcher()
  133. {
  134. }
  135.  
  136.  
  137. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  138. //    Ñ    
  139. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  140.  
  141. void CURLDispatcher::DispatchToStorage(
  142.     URL_Struct*                inURL,
  143.     const FSSpec&            inDestSpec,
  144.     FO_Present_Types        inOutputFormat,
  145.     Boolean                    inDelay)
  146. {
  147.     Assert_((inOutputFormat == FO_SAVE_AS) || (inOutputFormat == FO_SAVE_AS_TEXT));
  148.     
  149.     if (!inDelay)
  150.         {
  151.         CURLDispatchInfo* dispatchInfo = 
  152.             new CURLDispatchInfo(inURL, nil, inOutputFormat, inDelay, false, true);
  153.         dispatchInfo->SetFileSpec(inDestSpec);
  154.         if (inOutputFormat == FO_SAVE_AS)
  155.         {
  156.             DispatchToDisk(dispatchInfo);
  157.         }
  158.         else
  159.             DispatchToDiskAsText(dispatchInfo);
  160.         }
  161.     else
  162.         {
  163.         CURLDispatchInfo* theDelay =
  164.             new CURLDispatchInfo(inURL, nil, inOutputFormat, true, false, true);
  165.         theDelay->SetFileSpec(inDestSpec);
  166.         GetURLDispatcher()->PostPendingDispatch(theDelay);
  167.         }
  168. }
  169.  
  170. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  171. //    Ñ    
  172. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  173.  
  174. void CURLDispatcher::DispatchToStorage(CURLDispatchInfo* inDispatchInfo)
  175. {
  176.     Assert_((inDispatchInfo->GetOutputFormat() == FO_SAVE_AS) || (inDispatchInfo->GetOutputFormat() == FO_SAVE_AS_TEXT));
  177.     
  178.     if (!inDispatchInfo->GetDelay())
  179.         {
  180.         if (inDispatchInfo->GetOutputFormat() == FO_SAVE_AS)
  181.             DispatchToDisk(inDispatchInfo);
  182.         else
  183.             DispatchToDiskAsText(inDispatchInfo);
  184.         }
  185.     else
  186.         {
  187.         GetURLDispatcher()->PostPendingDispatch(inDispatchInfo);
  188.         }
  189. }
  190.  
  191. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  192. //    Ñ    
  193. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  194.  
  195. void CURLDispatcher::SpendTime(const EventRecord& /*inMacEvent*/)
  196. {
  197.     if (mDelayedURLs.GetCount() > 0)
  198.         ProcessPendingDispatch();
  199.     else
  200.         StopIdling();
  201. }
  202.  
  203. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  204. //    Ñ    
  205. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  206.         
  207. void CURLDispatcher::ListenToMessage(
  208.     MessageT                inMessage,
  209.     void*                    ioParam)
  210. {
  211.     if ((inMessage == msg_BroadcasterDied) && (mDelayedURLs.GetCount() > 0))
  212.         UpdatePendingDispatch((CNSContext*)ioParam);
  213. }
  214.  
  215.  
  216. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  217. //    Ñ    
  218. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  219.  
  220.  
  221. XP_List* gAppleDoubleSpecList = nil; // for the ad decoder (see ad_decode.c)
  222.  
  223. void CURLDispatcher::DispatchToDisk(CURLDispatchInfo* inDispatchInfo)
  224. {
  225.     CBrowserContext* theContext = NULL;
  226.     CDownloadProgressWindow* theProgressWindow = NULL;
  227.     FSSpec& destSpec = inDispatchInfo->GetFileSpec();
  228.     URL_Struct* inURL = inDispatchInfo->GetURLStruct();
  229.     
  230.     CAutoPtr<CURLDispatchInfo> info(inDispatchInfo);
  231.  
  232.     Assert_(inURL != NULL);
  233.  
  234.     try
  235.         {
  236.         theContext = new CBrowserContext(MWContextSaveToDisk);
  237.         StSharer theShareLock(theContext);
  238.         
  239.         theProgressWindow = dynamic_cast<CDownloadProgressWindow*>(URobustCreateWindow::CreateWindow(WIND_DownloadProgress, LCommander::GetTopCommander()));
  240.         ThrowIfNULL_(theProgressWindow);
  241.         theProgressWindow->Show();
  242.         
  243.         inURL->fe_data = StructCopy(&destSpec, sizeof(FSSpec));
  244.         if (destSpec.name[0] != '\0')
  245.         {
  246.             // Put the spec into our global variable where the ad decoder will find it.
  247.             if (!gAppleDoubleSpecList)
  248.                 gAppleDoubleSpecList = XP_ListNew();
  249.             FSSpec* spec = (FSSpec*)XP_ALLOC(sizeof(FSSpec));
  250.             FailNIL_(spec);
  251.             OSErr err = CFileMgr::UniqueFileSpec(destSpec, destSpec.name, *spec);
  252.             if (err)
  253.                 throw err;
  254.             XP_ListAddObjectToEnd(gAppleDoubleSpecList, spec);
  255.         }
  256.         theProgressWindow->SetWindowContext(theContext);
  257.         // the window will be shown on the first progress call.
  258.         
  259.         theContext->ImmediateLoadURL(inDispatchInfo->ReleaseURLStruct(), FO_SAVE_AS);
  260.         }
  261.     catch (...)
  262.         {
  263.         delete theProgressWindow;        
  264.         XP_ListDestroy(gAppleDoubleSpecList);
  265.         gAppleDoubleSpecList = nil;
  266.         throw;
  267.         }
  268. }
  269.  
  270. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  271. //    Ñ    
  272. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  273.  
  274.  
  275. extern "C" void SaveAsCompletionProc( PrintSetup* p );
  276.  
  277.  
  278. void CURLDispatcher::DispatchToDiskAsText(CURLDispatchInfo* inDispatchInfo)
  279. {
  280.     
  281.     CNSContext* theContext = NULL;
  282.     CDownloadProgressWindow* theProgressWindow = NULL;
  283.     FSSpec& destSpec = inDispatchInfo->GetFileSpec();
  284.     URL_Struct* inURL = inDispatchInfo->GetURLStruct();
  285.     
  286.     Assert_(inURL != NULL);
  287.  
  288.     try
  289.     {
  290.         theContext = new CNSContext(MWContextSaveToDisk);
  291.         StSharer theShareLock(theContext);
  292.         
  293.         theProgressWindow = dynamic_cast<CDownloadProgressWindow*>(URobustCreateWindow::CreateWindow(WIND_DownloadProgress, LCommander::GetTopCommander()));
  294.         ThrowIfNULL_(theProgressWindow);
  295.         theProgressWindow->SetWindowContext(theContext);
  296.         
  297.         CMimeMapper *theMapper = CPrefs::sMimeTypes.FindMimeType(CMimeList::HTMLViewer);
  298.         OSType creator = emSignature, docType='TEXT';
  299.         if (theMapper != NULL && CMimeMapper::Launch == theMapper->GetLoadAction())
  300.         {
  301.             creator = theMapper->GetAppSig();
  302.             docType = theMapper->GetDocType();
  303.         }
  304.         
  305.         OSErr theErr = ::FSpCreate(&destSpec, creator, docType, 0);
  306.         if ((theErr != noErr) && (theErr != dupFNErr))
  307.             ThrowIfOSErr_(theErr);
  308.         
  309.         CFileMgr::FileSetComment(destSpec, NET_URLStruct_Address(inURL));
  310.         
  311.         char* thePath = CFileMgr::EncodedPathNameFromFSSpec(destSpec, TRUE);
  312.         ThrowIfNULL_(thePath);
  313.         
  314.         thePath = NET_UnEscape(thePath);
  315.         XP_File theFile = XP_FileOpen(thePath, xpURL, XP_FILE_WRITE);
  316.         XP_FREE(thePath);
  317.         ThrowIfNULL_(theFile);
  318.         
  319.         PrintSetup print;
  320.         XL_InitializeTextSetup(&print);
  321.         print.width = 76;
  322.         print.out = theFile;
  323.         print.completion = (XL_CompletionRoutine) SaveAsCompletionProc;
  324.         print.carg = (void*)(theContext);
  325.         print.filename = nil;
  326.         print.url = inURL;
  327.         inURL->fe_data = theContext;
  328.         
  329.         MWContext* textContext = (MWContext*) XL_TranslateText(*theContext, inURL, &print);
  330.     }
  331.     catch(...)
  332.     {
  333.     }
  334. }
  335.  
  336.  
  337. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  338. //    Ñ    
  339. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  340.  
  341. void CURLDispatcher::PostPendingDispatch(CURLDispatchInfo* inDispatchInfo)
  342. {
  343.     mDelayedURLs.InsertItemsAt(1, LArray::index_Last, &inDispatchInfo, sizeof(CURLDispatchInfo*));
  344.     StartIdling();
  345.     if (inDispatchInfo->GetTargetContext() != NULL)
  346.         inDispatchInfo->GetTargetContext()->AddListener(this);
  347. }
  348.  
  349. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  350. //    Ñ    
  351. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  352.  
  353. void CURLDispatcher::UpdatePendingDispatch(
  354.     CNSContext*                inForContext)
  355. {
  356.     Assert_(inForContext != NULL);
  357.     
  358.     CURLDispatchInfo* theInfo;
  359.     LArrayIterator theIter(mDelayedURLs, LArrayIterator::from_Start);
  360.     while (theIter.Next(&theInfo))
  361.         {
  362.         if (theInfo->GetTargetContext() == inForContext)
  363.             mDelayedURLs.RemoveItemsAt(1, theIter.GetCurrentIndex());
  364.         }
  365. }
  366.  
  367. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  368. //    Ñ    
  369. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  370.  
  371. void CURLDispatcher::ProcessPendingDispatch(void)
  372. {
  373.     if (CFrontApp::GetApplication()->HasProperlyStartedUp())
  374.     {
  375.         CURLDispatchInfo* theInfo;
  376.         mDelayedURLs.FetchItemAt(LArray::index_First, &theInfo);
  377.         // 97-06-10 pkc -- Hack to workaround trying to dispatch URL's on image
  378.         // anchors while mocha is loading image
  379.         CBrowserContext* browserContext =
  380.             dynamic_cast<CBrowserContext*>(theInfo->GetTargetContext());
  381.         if (theInfo->GetIsWaitingForMochaImageLoad() &&
  382.             theInfo->GetTargetContext())
  383.         {
  384.             if (browserContext && browserContext->IsMochaLoadingImages())
  385.             {
  386.                 // The context is loading images for mocha, don't
  387.                 // perform dispatch
  388.                 return;
  389.             }
  390.         }
  391.         mDelayedURLs.RemoveItemsAt(1, LArray::index_First);
  392.         
  393.         if (theInfo->GetTargetContext() != NULL)
  394.             theInfo->GetTargetContext()->RemoveListener(this);
  395.  
  396.         theInfo->ClearDelay();
  397.  
  398.         if (theInfo->GetIsSaving())
  399.             DispatchToStorage(theInfo);
  400.         else
  401.         {
  402.             // See if this delayed URL was for an ftp drag &drop
  403.             if (theInfo->GetURLStruct()->files_to_post)
  404.             {
  405.                 // See if the user really meant to upload
  406.                 if (browserContext && !browserContext->Confirm((const char*)GetCString(MAC_UPLOAD_TO_FTP))) /* l10n */
  407.                 {
  408.                     // Delete the info if not
  409.                     delete theInfo;
  410.                 }
  411.                 else
  412.                 {
  413.                     // Ship it!
  414.                     DispatchURL(theInfo);
  415.                 }
  416.             }
  417.             else
  418.             {
  419.                 // Plain ordinary delayed URL
  420.                 DispatchURL(theInfo);
  421.             }
  422.         }
  423.     }
  424. }
  425.  
  426.  
  427. // 97-05-13 pkc
  428. // New URL dispatch mechanism.
  429.  
  430. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  431. //    Ñ    
  432. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  433.  
  434. void CURLDispatcher::DispatchURL(
  435.     const char*                inURL,
  436.     CNSContext*                inTargetContext,
  437.     Boolean                    inDelay,
  438.     Boolean                    inForceCreate,
  439.     ResIDT                    inWindowResID,
  440.     Boolean                    inInitiallyVisible,
  441.     FO_Present_Types        inOutputFormat,
  442.     NET_ReloadMethod        inReloadMethod)
  443. {
  444.     CURLDispatchInfo* dispatchInfo =
  445.         new CURLDispatchInfo(
  446.             inURL,
  447.             inTargetContext,
  448.             inOutputFormat,
  449.             inReloadMethod,
  450.             inDelay,
  451.             inForceCreate,
  452.             false,
  453.             inWindowResID,
  454.             inInitiallyVisible
  455.             );
  456.     DispatchURL(dispatchInfo);
  457. }
  458.  
  459. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  460. //    Ñ    
  461. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  462.  
  463. void CURLDispatcher::DispatchURL(
  464.     URL_Struct*                inURLStruct,
  465.     CNSContext*                inTargetContext,
  466.     Boolean                    inDelay,
  467.     Boolean                    inForceCreate,
  468.     ResIDT                    inWindowResID,
  469.     Boolean                    inInitiallyVisible,
  470.     FO_Present_Types        inOutputFormat,
  471.     Boolean                    inWaitingForMochaImageLoad)
  472. {
  473.     CURLDispatchInfo* dispatchInfo =
  474.         new CURLDispatchInfo(
  475.             inURLStruct,
  476.             inTargetContext,
  477.             inOutputFormat,
  478.             inDelay,
  479.             inForceCreate,
  480.             false,
  481.             inWindowResID,
  482.             inInitiallyVisible,
  483.             inWaitingForMochaImageLoad
  484.             );
  485.     DispatchURL(dispatchInfo);
  486. }
  487.  
  488.  
  489. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  490. //    Ñ    
  491. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  492.  
  493. void CURLDispatcher::DispatchURL(CURLDispatchInfo* inDispatchInfo)
  494. {
  495.     XP_ASSERT(inDispatchInfo != NULL);
  496.  
  497.     // FIX ME??? Does this go here?
  498.     sLastBrowserWindowCreated = NULL;
  499.     
  500.     // paranoia
  501.     if (inDispatchInfo)
  502.     {
  503.         if (inDispatchInfo->GetDelay())
  504.         {
  505.             GetURLDispatcher()->PostPendingDispatch(inDispatchInfo);
  506.         }
  507.         // Check to make sure URL type index is within dispatch table bounds
  508.         else if (inDispatchInfo->GetURLType() < cNumURLTypes)
  509.         { 
  510.             // Get dispatch proc from table
  511.             DispatchProcPtr dispatchProc = dispatchProcs[inDispatchInfo->GetURLType()];
  512.             if (dispatchProc)
  513.             {
  514.                 (*dispatchProc)(inDispatchInfo);
  515.             }
  516.         }
  517.     }
  518. }
  519.  
  520. #pragma mark -- Dispatch Procs --
  521.  
  522. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  523. //    Ñ    
  524. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  525.  
  526. void CURLDispatcher::DispatchToLibNet(CURLDispatchInfo* inDispatchInfo)
  527. {
  528.     CAutoPtr<CURLDispatchInfo> info(inDispatchInfo);
  529.     // If someone passed in a context, use it.
  530.     if (inDispatchInfo->GetTargetContext())
  531.     {
  532.         inDispatchInfo->GetTargetContext()->ImmediateLoadURL(inDispatchInfo->ReleaseURLStruct(), inDispatchInfo->GetOutputFormat());
  533.     }
  534.     else
  535.     {
  536.         try
  537.         {
  538.             if (!sDispatchContext.get())
  539.             {
  540.                 sDispatchContext.reset(new CBrowserContext());
  541.             }
  542.             sDispatchContext->ImmediateLoadURL(inDispatchInfo->ReleaseURLStruct(), inDispatchInfo->GetOutputFormat());
  543.         }
  544.         catch (...)
  545.         {
  546.         }
  547.     }
  548. }
  549.  
  550. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  551. //    Ñ    
  552. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  553.  
  554. void CURLDispatcher::DispatchToBrowserWindow(CURLDispatchInfo* inDispatchInfo)
  555. {
  556.     CAutoPtr<CURLDispatchInfo> info(inDispatchInfo);
  557.     if (!inDispatchInfo->GetDelay())
  558.     {
  559.         if (inDispatchInfo->GetForceCreate())
  560.         {
  561.             // Must create a new window
  562.             DispatchToNewBrowserWindow(info.release());
  563.         }
  564.         else if (inDispatchInfo->GetTargetContext())
  565.         {
  566.             // Use target context if passed in
  567.             // 97-09-18 pchen -- use target if it's not "_self"
  568.             // I found "_current" in npglue.c; do we need to filter that also?
  569.             if (inDispatchInfo->GetURLStruct()->window_target &&
  570.                 XP_STRCASECMP(inDispatchInfo->GetURLStruct()->window_target, "_self"))
  571.             {
  572.                 /* The thinking here is that if the URL specifies a preferred window target,
  573.                    it's not safe to use the given context.  There is a known case where
  574.                    this is so; it involves a link in a subframe which links to an image
  575.                    and contains a "target" tag.  In this case, we use the only context
  576.                    always known to be safe: the one belonging to the window itself.
  577.                    This is precisely correct if the tag is "target = _top".  I feel
  578.                    queasy guaranteeing that it's correct for other values of target
  579.                    as well, but pchen thinks it will always work.  So: */
  580.                 CBrowserContext    *topContext;
  581.                 topContext = ExtractBrowserContext(*inDispatchInfo->GetTargetContext());
  582.                 inDispatchInfo->SetTargetContext(topContext->GetTopContext());
  583.             }
  584.             (inDispatchInfo->GetTargetContext())->SwitchLoadURL(inDispatchInfo->ReleaseURLStruct(), inDispatchInfo->GetOutputFormat());
  585.         }
  586.         else
  587.         {
  588.             // Find topmost "regular" browser window and dispatch into that window
  589.             CWindowMediator* theMediator = CWindowMediator::GetWindowMediator();
  590.             CBrowserWindow* theTopWindow =
  591.                 dynamic_cast<CBrowserWindow*>(theMediator->FetchTopWindow(WindowType_Browser, regularLayerType, false));
  592.             if (theTopWindow)
  593.             {
  594.                 theTopWindow->Select();
  595.                 CNSContext* theCurrentContext = theTopWindow->GetWindowContext();
  596.                 theCurrentContext->SwitchLoadURL(inDispatchInfo->ReleaseURLStruct(), inDispatchInfo->GetOutputFormat());
  597.             }
  598.             else
  599.             {
  600.                 // No "regular" browser window available, so create one
  601.                 DispatchToNewBrowserWindow(info.release());
  602.             }
  603.         }
  604.     }
  605.     else
  606.     {
  607.         GetURLDispatcher()->PostPendingDispatch(info.release());
  608.     }
  609. }
  610.  
  611. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  612. //    Ñ    
  613. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  614.  
  615. void CURLDispatcher::DispatchMailboxURL(CURLDispatchInfo* inDispatchInfo)
  616. {
  617. #ifdef MOZ_MAIL_NEWS
  618.     const char* urlAddress = inDispatchInfo->GetURL();
  619.     
  620.     // Test to see if this is an attachment URL
  621.     if (XP_STRSTR(urlAddress, "?part=") || XP_STRSTR(urlAddress, "&part="))
  622.     {
  623.         // This is a mail attachment, dispatch to browser window
  624.           CURLDispatcher::DispatchToBrowserWindow(inDispatchInfo);
  625.     }
  626.     else if (inDispatchInfo->GetForceCreate())
  627.     {
  628.         CMessageWindow::OpenFromURL (urlAddress);
  629.         /* note: we can't handle an internal link (as in the clause just below), so
  630.            we don't bother trying. Just load the message and let the user ask again
  631.            once that's completed, if it's really important to go to an internal link. */
  632.     }
  633.     else if (XP_STRCHR(urlAddress, '#'))
  634.     {
  635.         // 97-06-08 pkc -- handle internal links here
  636.         if (inDispatchInfo->GetTargetContext())
  637.             inDispatchInfo->GetTargetContext()->SwitchLoadURL(
  638.                 inDispatchInfo->ReleaseURLStruct(),
  639.                 inDispatchInfo->GetOutputFormat());
  640.     }
  641.     else
  642.     {
  643.         // Otherwise, call DispatchToMailNewsWindow
  644.         DispatchToMailNewsWindow(inDispatchInfo);
  645.     }
  646. #endif // MOZ_MAIL_NEWS
  647. }
  648.  
  649. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  650. //    Ñ    
  651. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  652.  
  653. void CURLDispatcher::DispatchToMailNewsWindow(CURLDispatchInfo* inDispatchInfo)
  654. {
  655. #ifdef MOZ_MAIL_NEWS
  656.     CAutoPtr<CURLDispatchInfo> info(inDispatchInfo);
  657.     CAutoPtrXP<char> url(XP_STRDUP(inDispatchInfo->GetURL()));
  658.     
  659.     const char* urlAddress = url.get();
  660.  
  661.     // Otherwise, call CMessageWindow::OpenFromURL
  662.     switch (MSG_PaneTypeForURL(urlAddress))
  663.     {
  664.         case MSG_MAILINGLISTPANE:
  665.             // ? Open a list window to allow editing of this list?  
  666.             // Ask someone.  Phil?  Michelle?
  667.             break;
  668.             
  669.         case MSG_ADDRPANE:
  670.             // Can't happen, MSG_PaneTypeForURL doesn't return this type,  
  671.             // but a future release should, and MSG_NewWindowRequired should
  672.             // then return true.
  673.             break;
  674.             
  675.         case MSG_FOLDERPANE:
  676.             CMailNewsFolderWindow::FindAndShow(true);                
  677.             break;
  678.             
  679.         case MSG_THREADPANE:
  680.             CThreadWindow::OpenFromURL(urlAddress);
  681.             break;
  682.             
  683.         case MSG_MESSAGEPANE:
  684.             CMessageWindow::OpenFromURL((char*)urlAddress);
  685.             break;
  686.             
  687.         case MSG_SUBSCRIBEPANE:
  688.             // Can't happen, MSG_PaneTypeForURL doesn't return this type,  
  689.             // but a future release should, and MSG_NewWindowRequired should
  690.             // then return true.
  691.             // CSubscribePane::FindAndShow();
  692.             break;
  693.         
  694.         case MSG_ANYPANE:    // this gets returned for most URLs
  695.             
  696.         case MSG_COMPOSITIONPANE:
  697.             // presumably, this is from a mailto:, and we handle this already, below.
  698.         case MSG_SEARCHPANE:
  699.             // Already handled below.
  700.         default:
  701.             break;
  702.     }
  703. #endif // MOZ_MAIL_NEWS
  704. }
  705.  
  706. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  707. //    Ñ    
  708. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  709.  
  710. void CURLDispatcher::DispatchToNewBrowserWindow(CURLDispatchInfo* inDispatchInfo)
  711. {
  712.     CAutoPtr<CURLDispatchInfo> info(inDispatchInfo);
  713.     CBrowserWindow* theBrowserWindow = NULL;
  714.     CNSContext* theContext = NULL;
  715.     URL_Struct* theURLStruct = inDispatchInfo->GetURLStruct();
  716.     
  717.     XP_ASSERT(inDispatchInfo != NULL);
  718.     if (inDispatchInfo)
  719.     {
  720.         theBrowserWindow = CreateNewBrowserWindow(inDispatchInfo->GetWindowResID(), false);
  721.         if (theBrowserWindow)
  722.         {
  723.             theContext = theBrowserWindow->GetWindowContext();
  724.             if (theURLStruct != nil)
  725.             {
  726.                 if (theURLStruct->window_target && theURLStruct->window_target[0] != '_')
  727.                     {
  728.                     // Ñ do not assign special names
  729.                     theContext->SetDescriptor(theURLStruct->window_target);
  730.                     }
  731.                 if (theURLStruct->window_target)
  732.                     theURLStruct->window_target[0] = 0;
  733.                 theContext->ImmediateLoadURL(inDispatchInfo->ReleaseURLStruct(), inDispatchInfo->GetOutputFormat());
  734.             }
  735.             if (inDispatchInfo->GetInitiallyVisible()) theBrowserWindow->Show();
  736.         }
  737.     }
  738. }
  739.  
  740. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  741. //    Ñ    
  742. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  743.  
  744. CBrowserWindow* CURLDispatcher::CreateNewBrowserWindow(
  745.     ResIDT inWindowResID,
  746.     Boolean inInitiallyVisible)
  747. {
  748.     CBrowserWindow* theBrowserWindow = NULL;
  749.     CBrowserContext* theContext = NULL;
  750.     
  751.     try
  752.     {
  753.         theContext = new CBrowserContext();
  754.         StSharer theShareLock(theContext);
  755.         
  756.         theBrowserWindow =
  757.             dynamic_cast<CBrowserWindow*>(URobustCreateWindow::CreateWindow(inWindowResID, LCommander::GetTopCommander()));
  758.         ThrowIfNULL_(theBrowserWindow);
  759.  
  760.         theBrowserWindow->SetWindowContext(theContext);
  761.         sLastBrowserWindowCreated = theBrowserWindow;
  762.         if (inInitiallyVisible)
  763.             theBrowserWindow->Show();
  764.     }
  765.     catch (...)
  766.     {
  767.         delete theBrowserWindow;
  768.         throw;
  769.     }
  770.     
  771.     return theBrowserWindow;
  772. }
  773.  
  774. #pragma mark -
  775.  
  776. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  777. //    Ñ    
  778. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  779.  
  780. CURLDispatchInfo::CURLDispatchInfo()
  781.     :    mURLType(HTTP_TYPE_URL),
  782.         mURLStruct(NULL),
  783.         mTargetContext(NULL),
  784.         mOutputFormat(NET_DONT_RELOAD),
  785.         mDelayDispatch(false),
  786.         mIsSaving(false),
  787.         mForceCreate(false),
  788.         mInitiallyVisible(true),
  789.         mIsWaitingForMochaImageLoad(false),
  790.         mWindowResID(1010)
  791. {
  792. }
  793.  
  794. CURLDispatchInfo::CURLDispatchInfo(
  795.     const char*                inURL,
  796.     CNSContext*                inTargetContext,
  797.     FO_Present_Types        inOutputFormat,
  798.     NET_ReloadMethod        inReloadMethod,
  799.     Boolean                    inDelay,
  800.     Boolean                    inForceCreate,
  801.     Boolean                    inIsSaving,
  802.     ResIDT                    inWindowResID,
  803.     Boolean                    inInitiallyVisible)
  804.     :    mTargetContext(NULL),
  805.         mOutputFormat(inOutputFormat),
  806.         mDelayDispatch(inDelay),
  807.         mForceCreate(inForceCreate),
  808.         mIsSaving(inIsSaving),
  809.         mInitiallyVisible(inInitiallyVisible),
  810.         mIsWaitingForMochaImageLoad(false),
  811.         mWindowResID(inWindowResID)
  812. {
  813.     mURLStruct = NET_CreateURLStruct(inURL, inReloadMethod);
  814.     if (inTargetContext)
  815.     {
  816.         cstring theReferer = inTargetContext->GetCurrentURL();
  817.         if (theReferer.length() > 0)
  818.             mURLStruct->referer = XP_STRDUP(theReferer);
  819.         mTargetContext = inTargetContext;
  820.     }
  821.     mURLType = NET_URL_Type(inURL);
  822. }
  823.  
  824. CURLDispatchInfo::CURLDispatchInfo(
  825.     URL_Struct*                inURLStruct,
  826.     CNSContext*                inTargetContext,
  827.     FO_Present_Types        inOutputFormat,
  828.     Boolean                    inDelay,
  829.     Boolean                    inForceCreate,
  830.     Boolean                    inIsSaving,
  831.     ResIDT                    inWindowResID,
  832.     Boolean                    inInitiallyVisible,
  833.     Boolean                    inWaitingForMochaImageLoad)
  834.     :    mURLStruct(inURLStruct),
  835.         mTargetContext(inTargetContext),
  836.         mOutputFormat(inOutputFormat),
  837.         mDelayDispatch(inDelay),
  838.         mForceCreate(inForceCreate),
  839.         mIsSaving(inIsSaving),
  840.         mInitiallyVisible(inInitiallyVisible),
  841.         mIsWaitingForMochaImageLoad(inWaitingForMochaImageLoad),
  842.         mWindowResID(inWindowResID)
  843. {
  844.     if (inTargetContext && mURLStruct->referer == NULL)
  845.     {
  846.         cstring theReferer = inTargetContext->GetCurrentURL();
  847.         if (theReferer.length() > 0)
  848.             mURLStruct->referer = XP_STRDUP(theReferer);
  849.         mTargetContext = inTargetContext;
  850.     }
  851.     if (inURLStruct)
  852.         mURLType = NET_URL_Type(NET_URLStruct_Address(inURLStruct));
  853.     else
  854.         mURLType = 0;
  855. }
  856.  
  857. CURLDispatchInfo::~CURLDispatchInfo()
  858. {
  859.     if (mURLStruct)
  860.     {
  861.         NET_FreeURLStruct(mURLStruct);
  862.     }
  863. }
  864.  
  865. URL_Struct* CURLDispatchInfo::ReleaseURLStruct()
  866. {
  867.     URL_Struct* url = mURLStruct;
  868.     mURLStruct = NULL;
  869.     return url;
  870. }
  871.  
  872. char* CURLDispatchInfo::GetURL()
  873. {
  874.     if (mURLStruct)
  875.         return NET_URLStruct_Address(mURLStruct);
  876.     else
  877.         return NULL;
  878. }
  879.  
  880. void CURLDispatchInfo::SetFileSpec(const FSSpec& inFileSpec)
  881. {
  882.     mFileSpec = inFileSpec;
  883. }
  884.