Back to index

lightning-sunbird  0.9+nobinonly
nsViewerApp.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Brian Ryner <bryner@brianryner.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifdef NGPREFS
00040 #define INITGUID
00041 #endif
00042 
00043 #include "nsCOMPtr.h"
00044 #include "nsReadableUtils.h"
00045 #include "nsXPBaseWindow.h" 
00046 #include "nsViewerApp.h"
00047 #include "nsBrowserWindow.h"
00048 #include "nsWidgetsCID.h"
00049 #include "nsWindowCreator.h"
00050 #include "nsIAppShell.h"
00051 #include "nsIPref.h"
00052 #include "nsIWindowWatcher.h"
00053 
00054 // Form Processor
00055 #include "nsIFormProcessor.h"
00056 
00057 
00058 #include "nsIComponentManager.h"
00059 #include "nsIComponentRegistrar.h"
00060 #include "nsIServiceManager.h"
00061 #include "nsIFactory.h"
00062 #include "nsIEventQueueService.h"
00063 #include "nsIInterfaceRequestor.h"
00064 #include "nsIInterfaceRequestorUtils.h"
00065 #include "nsWebCrawler.h"
00066 #include "prprf.h"
00067 #include "plstr.h"
00068 #include "prenv.h"
00069 #include "nsIScriptGlobalObject.h"
00070 #include "nsIScriptContext.h"
00071 #include "nsGUIEvent.h"
00072 #include "nsStaticComponents.h"
00073 
00074 // Needed for Dialog GUI
00075 #include "nsICheckButton.h"
00076 #include "nsILabel.h"
00077 #include "nsIButton.h"
00078 #include "nsITextWidget.h"
00079 #include "nsILookAndFeel.h"
00080 #include "nsColor.h"
00081 #include "nsWidgetSupport.h"
00082 
00083 
00084 // XXX For font setting below
00085 #include "nsFont.h"
00086 #include "nsUnitConversion.h"
00087 #include "nsIDeviceContext.h"
00088 
00089 #include "nsIDOMHTMLSelectElement.h"
00090 
00091 #include "nsISupportsObsolete.h"
00092 
00093 // new widget stuff
00094 #ifdef USE_LOCAL_WIDGETS
00095   extern nsresult NS_NewButton(nsIButton** aControl);
00096   extern nsresult NS_NewLabel(nsILabel** aControl);
00097   extern nsresult NS_NewTextWidget(nsITextWidget** aControl);
00098   extern nsresult NS_NewCheckButton(nsICheckButton** aControl);
00099 #endif
00100 
00101 // cookie
00102 #include "nsNetCID.h"
00103 #include "nsICookieService.h"
00104 
00105 #define DIALOG_FONT      "Helvetica"
00106 #define DIALOG_FONT_SIZE 10
00107 
00108 
00109 #ifdef XP_WIN
00110 #include "JSConsole.h"
00111 #ifdef NGPREFS
00112 #include "ngprefs.h"
00113 #endif
00114 #endif
00115 #if defined(XP_WIN) && !defined(__MINGW32__)
00116 #include <crtdbg.h>
00117 #endif
00118 
00119 extern nsresult NS_NewXPBaseWindowFactory(nsIFactory** aFactory);
00120 
00121 static NS_DEFINE_IID(kAppShellCID, NS_APPSHELL_CID);
00122 static NS_DEFINE_IID(kXPBaseWindowCID, NS_XPBASE_WINDOW_CID);
00123 static NS_DEFINE_IID(kCookieServiceCID, NS_COOKIESERVICE_CID);
00124 
00125 static NS_DEFINE_IID(kIAppShellIID, NS_IAPPSHELL_IID);
00126 static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
00127 
00128 static NS_DEFINE_CID(kFormProcessorCID,   NS_FORMPROCESSOR_CID);
00129 
00130 #define DEFAULT_WIDTH 620
00131 #define DEFAULT_HEIGHT 400
00132 
00133 
00134 nsViewerApp::nsViewerApp()
00135 {
00136   char * text = PR_GetEnv("NGLAYOUT_HOME");
00137   mStartURL.AssignWithConversion(text ? text : "resource:/res/samples/test0.html");
00138 
00139   //rickg 20Nov98: For the sake of a good demo, pre-load a decent URL...
00140 //  mStartURL = text ? text : "http://developer.netscape.com/software/communicator/ngl/index.html";
00141 
00142   mDelay = 1;
00143   mRepeatCount = 1;
00144   mNumSamples = 14;
00145   mAllowPlugins = PR_TRUE;
00146   mIsInitialized = PR_FALSE;
00147   mWidth = DEFAULT_WIDTH;
00148   mHeight = DEFAULT_HEIGHT;
00149   mJustShutdown = PR_FALSE;
00150 }
00151 
00152 nsViewerApp::~nsViewerApp()
00153 {
00154   Destroy();
00155 }
00156 
00157 NS_IMPL_THREADSAFE_ADDREF(nsViewerApp)
00158 NS_IMPL_THREADSAFE_RELEASE(nsViewerApp)
00159 
00160 nsresult
00161 nsViewerApp::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) 
00162 {
00163   NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
00164   if (nsnull == aInstancePtrResult) {
00165     return NS_ERROR_NULL_POINTER;
00166   }
00167   if (aIID.Equals(kISupportsIID)) {
00168     nsISupports* tmp = this;
00169     *aInstancePtrResult = (void*) tmp;
00170     NS_ADDREF_THIS();
00171     return NS_OK;
00172   }
00173 #if defined(NS_DEBUG) 
00174   /*
00175    * Check for the debug-only interface indicating thread-safety
00176    */
00177   static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID);
00178   if (aIID.Equals(kIsThreadsafeIID)) {
00179     return NS_OK;
00180   }
00181 #endif /* NS_DEBUG */
00182 
00183   return NS_NOINTERFACE;
00184 }
00185 
00186 void
00187 nsViewerApp::Destroy()
00188 {
00189   // Close all of our windows
00190   nsBrowserWindow::CloseAllWindows();
00191 
00192   // Release the crawler
00193   if (nsnull != mCrawler) {
00194     // break cycle between crawler and window.
00195     mCrawler->SetBrowserWindow(nsnull);
00196     NS_RELEASE(mCrawler);
00197   }
00198 
00199   NS_IF_RELEASE(mPrefService);
00200 }
00201 
00202 #ifndef _BUILD_STATIC_BIN
00203 nsStaticModuleInfo const *const kPStaticModules = nsnull;
00204 PRUint32 const kStaticModuleCount = 0;
00205 #endif
00206 
00207 nsresult
00208 nsViewerApp::SetupRegistry()
00209 {
00210   nsresult rv;
00211 
00212   nsCOMPtr<nsIServiceManager> servManager;
00213   rv = NS_InitXPCOM3(getter_AddRefs(servManager), nsnull, nsnull,
00214                      kPStaticModules, kStaticModuleCount);
00215 
00216   nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servManager);
00217   NS_ASSERTION(registrar, "No nsIComponentRegistrar from get service. see dougt");
00218   rv = registrar->AutoRegister(nsnull);
00219 
00220   // Register our browser window factory
00221   nsIFactory* bwf;
00222   NS_NewXPBaseWindowFactory(&bwf);
00223   registrar->RegisterFactory(kXPBaseWindowCID, 0, 0, bwf);
00224   NS_RELEASE(bwf);
00225 
00226   // register the cookie manager
00227   nsCOMPtr<nsICookieService> cookieService = 
00228            do_GetService(kCookieServiceCID, &rv);
00229   if (NS_FAILED(rv) || (nsnull == cookieService)) {
00230 #ifdef DEBUG
00231     printf("Unable to instantiate Cookie Manager\n");
00232 #endif
00233   }
00234 
00235   return NS_OK;
00236 }
00237 
00238 nsresult
00239 nsViewerApp::Initialize(int argc, char** argv)
00240 {
00241   nsresult rv;
00242 
00243   rv = SetupRegistry();
00244   if (NS_FAILED(rv)) {
00245     return rv;
00246   }
00247 
00248   InitializeWindowCreator();
00249 
00250   // Create widget application shell
00251   rv = CallCreateInstance(kAppShellCID, &mAppShell);
00252   if (NS_FAILED(rv)) {
00253     return rv;
00254   }
00255   mAppShell->Create(&argc, argv);
00256 
00257   // Load preferences
00258   rv = CallGetService(NS_PREFSERVICE_CONTRACTID, &mPrefService);
00259   if (NS_FAILED(rv)) {
00260     return rv;
00261   }
00262   mPrefService->ReadUserPrefs(nsnull);
00263 
00264   // Finally process our arguments
00265   rv = ProcessArguments(argc, argv);
00266 
00267   mIsInitialized = PR_TRUE;
00268   return rv;
00269 }
00270 
00271 /* InitializeWindowCreator creates and hands off an object with a callback
00272    to a window creation function. This is how all new windows are opened,
00273    except any created directly by the viewer app. */
00274 nsresult
00275 nsViewerApp::InitializeWindowCreator()
00276 {
00277   // create an nsWindowCreator and give it to the WindowWatcher service
00278   nsWindowCreator *creatorCallback = new nsWindowCreator(this);
00279   if (creatorCallback) {
00280     nsCOMPtr<nsIWindowCreator> windowCreator(NS_STATIC_CAST(nsIWindowCreator *, creatorCallback));
00281     if (windowCreator) {
00282       nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
00283       if (wwatch) {
00284         wwatch->SetWindowCreator(windowCreator);
00285         return NS_OK;
00286       }
00287     }
00288   }
00289   return NS_ERROR_FAILURE;
00290 }
00291 
00292 nsresult
00293 nsViewerApp::Exit()
00294 {
00295   nsresult rv = NS_OK;
00296   if (mAppShell) {
00297     Destroy();
00298     mAppShell->Exit();
00299     NS_RELEASE(mAppShell);
00300   }
00301 
00302   return rv;
00303 }
00304 
00305 static void
00306 PrintHelpInfo(char **argv)
00307 {
00308   fprintf(stderr, "Usage: %s [options] [starting url]\n", argv[0]);
00309   fprintf(stderr, "-M -- measure (and show) page load time\n");
00310   fprintf(stderr, "-p[#]   -- autload tests 0-#\n");
00311   fprintf(stderr, "-q -- jiggles window width after page has autoloaded\n");
00312   fprintf(stderr, "-f filename -- read a list of URLs to autoload from <filename>\n");
00313   fprintf(stderr, "-d # -- set the delay between autoloads to # (in milliseconds)\n");
00314   fprintf(stderr, "-np -- no plugins\n");
00315   fprintf(stderr, "-v -- verbose (debug noise)\n");
00316   fprintf(stderr, "-r # -- how many times a page is loaded when autoloading\n");
00317   fprintf(stderr, "-o dirname -- create an output file for the frame dump of each page\n  and put it in <dirname>. <dirname> must include the trailing\n  <slash> character appropriate for your OS\n");
00318   fprintf(stderr, "-rd dirname -- specify a regression directory whose contents are from\n  a previous -o run to compare against with this run\n");
00319   fprintf(stderr, "-regnostyle -- exclude style data from the regression test output: valid only with -o and -rd\n");
00320   fprintf(stderr, "-h # -- the initial height of the viewer window\n");
00321   fprintf(stderr, "-w # -- the initial width of the viewer window\n");
00322   fprintf(stderr, "-C -- enable crawler\n");
00323   fprintf(stderr, "-R filename -- record pages crawled to in <filename>\n");
00324   fprintf(stderr, "-S domain -- add a domain/host that is safe to crawl (e.g. www.netscape.com)\n");
00325   fprintf(stderr, "-A domain -- add a domain/host that should be avoided (e.g. microsoft.com)\n");
00326   fprintf(stderr, "-N pages -- set the max # of pages to crawl\n");
00327   fprintf(stderr, "-x -- startup and just shutdown to test for leaks under Purify\n");
00328   fprintf(stderr, "-Prt -- number of the printer test 1=regression, no printout \n");
00329   fprintf(stderr, "-B -- Setting for regression output 1=brief, 2=verbose \n");
00330 #if defined(NS_DEBUG) && defined(XP_WIN)
00331   fprintf(stderr, "-md # -- set the crt debug flags to #\n");
00332 #endif
00333 }
00334 
00335 static void
00336 AddTestDocsFromFile(nsWebCrawler* aCrawler, const nsString& aFileName)
00337 {
00338   NS_LossyConvertUCS2toASCII cfn(aFileName);
00339 #if defined(XP_WIN) || defined(XP_OS2)
00340   FILE* fp = fopen(cfn.get(), "rb");
00341 #else
00342   FILE* fp = fopen(cfn.get(), "r");
00343 #endif
00344 
00345   if (nsnull==fp)
00346   {
00347     fprintf(stderr, "Input file not found: %s\n", cfn.get());
00348     exit (-1);
00349   }
00350   nsAutoString line;
00351   for (;;) {
00352     char linebuf[2000];
00353     char* cp = fgets(linebuf, sizeof(linebuf), fp);
00354     if (nsnull == cp) {
00355       break;
00356     }
00357     if (linebuf[0] == '#') {
00358       continue;
00359     }
00360 
00361     // strip crlf's from the line
00362     int len = strlen(linebuf);
00363     if (0 != len) {
00364       if (('\n' == linebuf[len-1]) || ('\r' == linebuf[len-1])) {
00365         linebuf[--len] = 0;
00366       }
00367     }
00368     if (0 != len) {
00369       if (('\n' == linebuf[len-1]) || ('\r' == linebuf[len-1])) {
00370         linebuf[--len] = 0;
00371       }
00372     }
00373 
00374     // Add non-empty lines to the test list
00375     if (0 != len) {
00376       line.AssignWithConversion(linebuf);
00377       aCrawler->AddURL(line);
00378     }
00379   }
00380 
00381   fclose(fp);
00382 }
00383 
00384 NS_IMETHODIMP
00385 nsViewerApp::ProcessArguments(int argc, char** argv)
00386 {
00387   mCrawler = new nsWebCrawler(this);
00388   NS_ADDREF(mCrawler);
00389 
00390   int i;
00391   for (i = 1; i < argc; i++) {
00392     if (argv[i][0] == '-') {
00393       if (PL_strcmp(argv[i], "-x") == 0) {
00394         mJustShutdown = PR_TRUE;
00395       }
00396 #if defined(NS_DEBUG) && defined(XP_WIN) && !defined(__MINGW32__)
00397       else if (PL_strcmp(argv[i], "-md") == 0) {
00398         int old = _CrtSetDbgFlag(0);
00399         old |= _CRTDBG_CHECK_ALWAYS_DF;
00400         _CrtSetDbgFlag(old);
00401       }
00402 #endif
00403 #if defined(XP_MACOSX)
00404       else if (PL_strncmp(argv[i], "-psn_", 5) == 0) {
00405         continue;
00406       }
00407 #endif
00408       else if (PL_strncmp(argv[i], "-p", 2) == 0) {
00409         char *optionalSampleStopIndex = &(argv[i][2]);
00410         if ('\0' != *optionalSampleStopIndex)
00411         {
00412           if (1!=sscanf(optionalSampleStopIndex, "%d", &mNumSamples))
00413           {
00414             PrintHelpInfo(argv);
00415             exit(-1);
00416           }
00417         }
00418         mDoPurify = PR_TRUE;
00419         mCrawler->SetExitOnDone(PR_TRUE);
00420         mCrawl = PR_TRUE;
00421       }
00422       else if (PL_strcmp(argv[i], "-q") == 0) {
00423         mCrawler->EnableJiggleLayout();
00424         mCrawler->SetExitOnDone(PR_TRUE);
00425         mCrawl = PR_TRUE;
00426       }
00427       else if (PL_strcmp(argv[i], "-f") == 0) {
00428         mLoadTestFromFile = PR_TRUE;
00429         i++;
00430         if (i>=argc || nsnull==argv[i] || nsnull==*(argv[i]))
00431         {
00432           PrintHelpInfo(argv);
00433           exit(-1);
00434         }
00435         mInputFileName.AssignWithConversion(argv[i]);
00436         mCrawler->SetExitOnDone(PR_TRUE);
00437         mCrawl = PR_TRUE;
00438       }
00439       else if (PL_strcmp(argv[i], "-rd") == 0) {
00440         i++;
00441         if (i>=argc || nsnull==argv[i] || nsnull==*(argv[i])) {
00442           PrintHelpInfo(argv);
00443           exit(-1);
00444         }
00445         mCrawler->SetEnableRegression(PR_TRUE);
00446         mCrawler->SetRegressionDir(NS_ConvertASCIItoUCS2(argv[i]));
00447       }
00448       else if (PL_strcmp(argv[i], "-o") == 0) {
00449         i++;
00450         if (i>=argc || nsnull==argv[i] || nsnull==*(argv[i]))
00451         {
00452           PrintHelpInfo(argv);
00453           exit(-1);
00454         }
00455         mCrawler->SetOutputDir(NS_ConvertASCIItoUCS2(argv[i]));
00456       }
00457       else if (PL_strcmp(argv[i], "-w") == 0) {
00458         int width;
00459         i++;
00460         if (i>=argc || 1!=sscanf(argv[i], "%d", &width))
00461         {
00462           PrintHelpInfo(argv);
00463           exit(-1);
00464         }
00465         mWidth = width > 0 ? width : DEFAULT_WIDTH;
00466       }
00467       else if (PL_strcmp(argv[i], "-h") == 0) {
00468         int height;
00469         i++;
00470         if (i>=argc || 1!=sscanf(argv[i], "%d", &height))
00471         {
00472           PrintHelpInfo(argv);
00473           exit(-1);
00474         }
00475         mHeight = height > 0 ? height : DEFAULT_HEIGHT;
00476       }
00477       else if (PL_strcmp(argv[i], "-r") == 0) {
00478         i++;
00479         if (i>=argc || 1!=sscanf(argv[i], "%d", &mRepeatCount))
00480         {
00481           PrintHelpInfo(argv);
00482           exit(-1);
00483         }
00484       }
00485       else if (PL_strcmp(argv[i], "-C") == 0) {
00486         mCrawler->EnableCrawler();
00487         mCrawler->SetExitOnDone(PR_TRUE);
00488         mCrawl = PR_TRUE;
00489       }
00490       else if (PL_strcmp(argv[i], "-R") == 0) {
00491         i++;
00492         if (i>=argc) {
00493           PrintHelpInfo(argv);
00494           exit(-1);
00495         }
00496         FILE* fp = fopen(argv[i], "w");
00497         if (nsnull == fp) {
00498           fprintf(stderr, "can't create '%s'\n", argv[i]);
00499           exit(-1);
00500         }
00501         mCrawler->SetRecordFile(fp);
00502       }
00503       else if (PL_strcmp(argv[i], "-S") == 0) {
00504         i++;
00505         if (i>=argc) {
00506           PrintHelpInfo(argv);
00507           exit(-1);
00508         }
00509         mCrawler->AddSafeDomain(NS_ConvertASCIItoUCS2(argv[i]));
00510       }
00511       else if (PL_strcmp(argv[i], "-A") == 0) {
00512         i++;
00513         if (i>=argc) {
00514           PrintHelpInfo(argv);
00515           exit(-1);
00516         }
00517         mCrawler->AddAvoidDomain(NS_ConvertASCIItoUCS2(argv[i]));
00518       }
00519       else if (PL_strcmp(argv[i], "-N") == 0) {
00520         int pages;
00521         i++;
00522         if (i>=argc || 1!=sscanf(argv[i], "%d", &pages)) {
00523           PrintHelpInfo(argv);
00524           exit(-1);
00525         }
00526         mCrawler->SetMaxPages(pages);
00527       }
00528       else if (PL_strcmp(argv[i], "-np") == 0) {
00529         mAllowPlugins = PR_FALSE;
00530       }
00531       else if (PL_strcmp(argv[i], "-v") == 0) {
00532         mCrawler->SetVerbose(PR_TRUE);
00533       }
00534       else if (PL_strcmp(argv[i], "-M") == 0) {
00535         mShowLoadTimes = PR_TRUE;
00536       }
00537       else if (PL_strcmp(argv[i], "-?") == 0) {
00538         PrintHelpInfo(argv);
00539       }
00540       else if (PL_strcmp(argv[i], "-B") == 0) {
00541         int regressionOutput;
00542         i++;
00543         if (i>=argc || 1!=sscanf(argv[i], "%d", &regressionOutput)){
00544           PrintHelpInfo(argv);
00545           exit(-1);
00546         }
00547         mCrawler->RegressionOutput(regressionOutput);
00548       }
00549       else if (PL_strcmp(argv[i], "-Prt") == 0) {
00550         int printTestType;
00551         i++;
00552         if (i>=argc || 1!=sscanf(argv[i], "%d", &printTestType)){
00553           PrintHelpInfo(argv);
00554           exit(-1);
00555         }
00556         mCrawler->SetPrintTest(printTestType);
00557       }
00558       else if(PL_strcmp(argv[i], "-regnostyle") == 0) {
00559         mCrawler->IncludeStyleData(PR_FALSE);
00560       }
00561     }
00562     else
00563       break;
00564   }
00565   if (i < argc) {
00566     mStartURL.AssignWithConversion(argv[i]);
00567 #if defined(XP_UNIX) || defined(XP_BEOS)
00568     if (argv[i][0] == '/') {
00569       mStartURL.Assign(NS_LITERAL_STRING("file:") + mStartURL);
00570     }
00571 #endif
00572   }
00573   return NS_OK;
00574 }
00575 
00576 NS_IMETHODIMP
00577 nsViewerApp::OpenWindow()
00578 {
00579   // Create browser window
00580   // XXX Some piece of code needs to properly hold the reference to this
00581   // browser window. For the time being the reference is released by the
00582   // browser event handling code during processing of the NS_DESTROY event...
00583   nsBrowserWindow* bw = new nsNativeBrowserWindow();
00584   NS_ENSURE_TRUE(bw, NS_ERROR_FAILURE);
00585   NS_ADDREF(bw);
00586 
00587   bw->SetApp(this);
00588   bw->SetShowLoadTimes(mShowLoadTimes);
00589   bw->Init(mAppShell, nsRect(0, 0, mWidth, mHeight),
00590            (PRUint32(~0) & ~nsIWebBrowserChrome::CHROME_OPENAS_CHROME), mAllowPlugins);
00591   bw->SetVisibility(PR_TRUE);
00592   nsBrowserWindow*   bwCurrent;
00593   mCrawler->GetBrowserWindow(&bwCurrent);
00594   if (!bwCurrent) {
00595          mCrawler->SetBrowserWindow(bw);
00596     bw->SetWebCrawler(mCrawler);
00597   }
00598   NS_IF_RELEASE(bwCurrent);
00599 
00600   if (mDoPurify) {
00601     for (PRInt32 i = 0; i < mRepeatCount; i++) {
00602       for (int docnum = 0; docnum < mNumSamples; docnum++) {
00603         char url[500];
00604         PR_snprintf(url, 500, "%s/test%d.html", SAMPLES_BASE_URL, docnum);
00605         mCrawler->AddURL(NS_ConvertASCIItoUCS2(url));
00606       }
00607     }
00608     mCrawler->Start();
00609   }
00610   else if (mLoadTestFromFile) {
00611     for (PRInt32 i = 0; i < mRepeatCount; i++) {
00612       AddTestDocsFromFile(mCrawler, mInputFileName);
00613     }
00614     mCrawler->Start();
00615   }
00616   else if (mCrawl) {
00617     mCrawler->AddURL(mStartURL);
00618     mCrawler->Start();
00619   }
00620   else {
00621     bw->GoTo(mStartURL.get());
00622   }
00623   NS_RELEASE(bw);
00624 
00625   return NS_OK;
00626 }
00627 
00628 NS_IMETHODIMP
00629 nsViewerApp::CloseWindow(nsBrowserWindow* aBrowserWindow)
00630 {
00631   aBrowserWindow->Destroy();
00632   nsBrowserWindow* bw;
00633   mCrawler->GetBrowserWindow(&bw);
00634   if (bw == aBrowserWindow) {
00635     mCrawler->SetBrowserWindow(nsnull);
00636   }
00637   NS_IF_RELEASE(bw);
00638   NS_RELEASE(aBrowserWindow);
00639 
00640   return NS_OK;
00641 }
00642 
00643 NS_IMETHODIMP
00644 nsViewerApp::ViewSource(nsString& aURL)
00645 {
00646   // Create browser window
00647   // XXX Some piece of code needs to properly hold the reference to this
00648   // browser window. For the time being the reference is released by the
00649   // browser event handling code during processing of the NS_DESTROY event...
00650   nsBrowserWindow* bw = new nsNativeBrowserWindow();
00651   NS_ENSURE_TRUE(bw, NS_ERROR_FAILURE);
00652   NS_ADDREF(bw);
00653 
00654   bw->SetApp(this);
00655   bw->Init(mAppShell, nsRect(0, 0, 620, 400), PRUint32(~0), mAllowPlugins);
00656   bw->SetTitle(NS_LITERAL_STRING("View Source").get());
00657   bw->SetVisibility(PR_TRUE);
00658 
00659   bw->GoTo(PromiseFlatString(NS_LITERAL_STRING("view-source:") + aURL).get());
00660 
00661   NS_RELEASE(bw);
00662 
00663   return NS_OK;
00664 }
00665 
00666 NS_IMETHODIMP
00667 nsViewerApp::OpenWindow(PRUint32 aNewChromeMask, nsBrowserWindow*& aNewWindow)
00668 {
00669   // Create browser window
00670   nsBrowserWindow* bw = new nsNativeBrowserWindow();
00671   NS_ENSURE_TRUE(bw, NS_ERROR_FAILURE);
00672   NS_ADDREF(bw);
00673 
00674   bw->SetApp(this);
00675   bw->Init(mAppShell, nsRect(0, 0, 620, 400), aNewChromeMask, mAllowPlugins);
00676   // Defer showing chrome windows until the chrome has loaded
00677   if (!(aNewChromeMask & nsIWebBrowserChrome::CHROME_OPENAS_CHROME))
00678     bw->SetVisibility(PR_TRUE);
00679 
00680   aNewWindow = bw;
00681 
00682   return NS_OK;
00683 }
00684 
00685 //----------------------------------------
00686 
00687 #include "prenv.h"
00688 #include "resources.h"
00689 #include "nsIPresShell.h"
00690 #include "nsIDocument.h"
00691 #include "nsIURL.h"
00692 
00693 #if !defined(XP_WIN) && !defined(XP_OS2)
00694 #ifndef XP_MAC
00695 #define _MAX_PATH 512
00696 #endif
00697 #endif
00698 
00699 #define DEBUG_EMPTY "(none)"
00700 static PRInt32 gDebugRobotLoads = 5000;
00701 static char    gVerifyDir[_MAX_PATH];
00702 static PRBool  gVisualDebug = PR_TRUE;
00703 
00704 // Robot
00705 static nsIWidget      * mRobotDialog = nsnull;
00706 static nsIButton      * mCancelBtn;
00707 static nsIButton      * mStartBtn;
00708 static nsITextWidget  * mVerDirTxt;
00709 static nsITextWidget  * mStopAfterTxt;
00710 static nsICheckButton * mUpdateChkBtn;
00711 
00712 // Site
00713 static nsIWidget * mSiteDialog = nsnull;
00714 static nsIButton      * mSiteCancelBtn;
00715 static nsIButton      * mSitePrevBtn;
00716 static nsIButton      * mSiteNextBtn;
00717 static nsILabel       * mSiteLabel;
00718 static nsIButton      * mSiteJumpBtn;
00719 static nsITextWidget  * mSiteIndexTxt;
00720 
00721 static NS_DEFINE_IID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
00722 static NS_DEFINE_IID(kButtonCID,      NS_BUTTON_CID);
00723 static NS_DEFINE_IID(kTextFieldCID,   NS_TEXTFIELD_CID);
00724 static NS_DEFINE_IID(kWindowCID,      NS_WINDOW_CID);
00725 static NS_DEFINE_IID(kCheckButtonCID, NS_CHECKBUTTON_CID);
00726 static NS_DEFINE_IID(kLabelCID,       NS_LABEL_CID);
00727 
00728 
00729 static NS_DEFINE_IID(kIButtonIID,      NS_IBUTTON_IID);
00730 static NS_DEFINE_IID(kITextWidgetIID,  NS_ITEXTWIDGET_IID);
00731 static NS_DEFINE_IID(kIWidgetIID,      NS_IWIDGET_IID);
00732 static NS_DEFINE_IID(kICheckButtonIID, NS_ICHECKBUTTON_IID);
00733 static NS_DEFINE_IID(kILabelIID,       NS_ILABEL_IID);
00734 
00735 
00736 static void* GetWidgetNativeData(nsISupports* aObject)
00737 {
00738        void*                result = nsnull;
00739        nsIWidget*    widget;
00740        if (NS_OK == aObject->QueryInterface(kIWidgetIID,(void**)&widget))
00741        {
00742               result = widget->GetNativeData(NS_NATIVE_WIDGET);
00743               NS_RELEASE(widget);
00744        }
00745        return result;
00746 }
00747 
00748 
00749 
00750 
00751 #ifdef XP_WIN
00752 extern JSConsole *gConsole;
00753 // XXX temporary robot code until it's made XP
00754 extern HINSTANCE gInstance, gPrevInstance;
00755 
00756 extern "C" NS_EXPORT int DebugRobot(
00757   nsVoidArray * workList, nsIDocShell * ww,
00758   int imax, char * verify_dir,
00759   void (*yieldProc)(const char *));
00760 
00761 void yieldProc(const char * str)
00762 {
00763   // Process messages
00764   MSG msg;
00765   while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
00766     GetMessage(&msg, NULL, 0, 0);
00767     if (!JSConsole::sAccelTable ||
00768         !gConsole ||
00769         !gConsole->GetMainWindow() ||
00770         !TranslateAccelerator(gConsole->GetMainWindow(),
00771                               JSConsole::sAccelTable, &msg)) {
00772       TranslateMessage(&msg);
00773       DispatchMessage(&msg);
00774     }
00775   }
00776 }
00777 #endif
00778 
00779 
00784 static
00785 nsEventStatus PR_CALLBACK HandleRobotEvent(nsGUIEvent *aEvent)
00786 {
00787   nsEventStatus result = nsEventStatus_eIgnore;
00788   if (aEvent == nsnull ||  aEvent->widget == nsnull) {
00789     return result;
00790   }
00791 
00792   switch(aEvent->message) {
00793     case NS_MOUSE_LEFT_BUTTON_UP: {
00794       if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mCancelBtn)) {
00795         NS_ShowWidget(mRobotDialog,PR_FALSE);
00796       } else if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mStartBtn)) {
00797 
00798         nsString str;
00799         PRUint32 size;
00800 
00801         mStopAfterTxt->GetText(str, 255, size);
00802         char * cStr = ToNewCString(str);
00803         sscanf(cStr, "%d", &gDebugRobotLoads);
00804         if (gDebugRobotLoads <= 0) {
00805           gDebugRobotLoads = 5000;
00806         }
00807         delete[] cStr;
00808 
00809         mVerDirTxt->GetText(str, 255, size);
00810         str.ToCString(gVerifyDir, (PRInt32)_MAX_PATH);
00811         if (!strcmp(gVerifyDir,DEBUG_EMPTY)) {
00812           gVerifyDir[0] = '\0';
00813         }
00814         PRBool state = PR_FALSE;
00815         mUpdateChkBtn->GetState(state);
00816         gVisualDebug = state ? PR_TRUE: PR_FALSE;
00817 
00818       } 
00819 
00820       } break;
00821     
00822     case NS_PAINT: 
00823 #ifndef XP_UNIX
00824         // paint the background
00825         if (aEvent->widget == mRobotDialog ) {
00826           nsIRenderingContext *drawCtx = ((nsPaintEvent*)aEvent)->renderingContext;
00827           drawCtx->SetColor(aEvent->widget->GetBackgroundColor());
00828           drawCtx->FillRect(*(((nsPaintEvent*)aEvent)->rect));
00829 
00830           return nsEventStatus_eIgnore;
00831       }
00832 #endif
00833       return nsEventStatus_eIgnore;
00834       break;
00835 
00836     default:
00837       result = nsEventStatus_eIgnore;
00838   } //switch
00839 
00840   return result;
00841 }
00842 
00843 //--------------------------------------------
00844 //
00845 //--------------------------------------------
00846 static
00847 PRBool CreateRobotDialog(nsIWidget * aParent)
00848 {
00849   PRBool result = PR_TRUE;
00850 
00851   if (mRobotDialog != nsnull) {
00852     NS_ShowWidget(mRobotDialog,PR_TRUE);
00853     NS_SetFocusToWidget(mStartBtn);
00854     return PR_TRUE;
00855   }
00856 
00857    nsILabel * label;
00858 
00859   nsIDeviceContext* dc = aParent->GetDeviceContext();
00860   float t2d;
00861   t2d = dc->TwipsToDevUnits();
00862   nsFont font(DIALOG_FONT, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
00863               NS_FONT_WEIGHT_NORMAL, 0,
00864               nscoord(t2d * NSIntPointsToTwips(DIALOG_FONT_SIZE)));
00865   NS_RELEASE(dc);
00866 
00867   nscoord dialogWidth = 375;
00868   // create a Dialog
00869   //
00870   nsRect rect;
00871   rect.SetRect(0, 0, dialogWidth, 162);  
00872 
00873   CallCreateInstance(kWindowCID, &mRobotDialog);
00874   if (nsnull == mRobotDialog)
00875        return PR_FALSE;
00876 
00877   nsIWidget* dialogWidget = nsnull;
00878   if (NS_OK == mRobotDialog->QueryInterface(kIWidgetIID,(void**)&dialogWidget))
00879   {
00880     dialogWidget->Create(aParent, rect, HandleRobotEvent, NULL);
00881     NS_RELEASE(dialogWidget);
00882   }
00883   
00884   //mRobotDialog->SetLabel("Debug Robot Options");
00885 
00886   nscoord txtHeight   = 24;
00887   nscolor textBGColor = NS_RGB(255,255,255);
00888   nscolor textFGColor = NS_RGB(255,255,255);
00889 
00890   {
00891     nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID);
00892     if (lookAndFeel) {
00893       lookAndFeel->GetMetric(nsILookAndFeel::eMetric_TextFieldHeight, txtHeight);
00894       lookAndFeel->GetColor(nsILookAndFeel::eColor_TextBackground, textBGColor);
00895       lookAndFeel->GetColor(nsILookAndFeel::eColor_TextForeground, textFGColor);
00896     }
00897   }
00898   
00899   nscoord w  = 65;
00900   nscoord x  = 5;
00901   nscoord y  = 10;
00902 
00903   // Create Update CheckButton
00904   rect.SetRect(x, y, 150, 24);  
00905 #ifdef USE_LOCAL_WIDGETS
00906   NS_NewCheckButton(&mUpdateChkBtn);
00907 #else
00908   CallCreateInstance(kCheckButtonCID, &mUpdateChkBtn);
00909 #endif
00910   NS_CreateCheckButton(mRobotDialog, mUpdateChkBtn,rect,HandleRobotEvent,&font);
00911   mUpdateChkBtn->SetLabel(NS_ConvertASCIItoUCS2("Update Display (Visual)"));
00912   mUpdateChkBtn->SetState(PR_TRUE);
00913   y += 24 + 2;
00914 
00915   // Create Label
00916   w = 115;
00917   rect.SetRect(x, y+3, w, 24);  
00918 #ifdef USE_LOCAL_WIDGETS
00919   NS_NewLabel(&label);
00920 #else
00921   CallCreateInstance(kLabelCID, &label);
00922 #endif
00923   NS_CreateLabel(mRobotDialog,label,rect,HandleRobotEvent,&font);
00924   label->SetAlignment(eAlign_Right);
00925   label->SetLabel(NS_ConvertASCIItoUCS2("Verfication Directory:"));
00926   x += w + 1;
00927 
00928   // Create TextField
00929   nsIWidget* widget = nsnull;
00930   rect.SetRect(x, y, 225, txtHeight);  
00931 #ifdef USE_LOCAL_WIDGETS
00932   NS_NewTextWidget(&mVerDirTxt);
00933 #else
00934   CallCreateInstance(kTextFieldCID, &mVerDirTxt);
00935 #endif
00936   NS_CreateTextWidget(mRobotDialog,mVerDirTxt,rect,HandleRobotEvent,&font);
00937   if (mVerDirTxt && NS_OK == mVerDirTxt->QueryInterface(kIWidgetIID,(void**)&widget))
00938   {
00939     widget->SetBackgroundColor(textBGColor);
00940     widget->SetForegroundColor(textFGColor);
00941   }
00942   nsString str; str.AssignWithConversion(DEBUG_EMPTY);
00943   PRUint32 size;
00944   mVerDirTxt->SetText(str,size);
00945 
00946   y += txtHeight + 2;
00947   
00948   x = 5;
00949   w = 55;
00950   rect.SetRect(x, y+4, w, 24);  
00951 #ifdef USE_LOCAL_WIDGETS
00952   NS_NewLabel(&label);
00953 #else
00954   CallCreateInstance(kLabelCID, &label);
00955 #endif
00956   NS_CreateLabel(mRobotDialog,label,rect,HandleRobotEvent,&font);
00957   label->SetAlignment(eAlign_Right);
00958   label->SetLabel(NS_ConvertASCIItoUCS2("Stop after:"));
00959   x += w + 2;
00960 
00961   // Create TextField
00962   rect.SetRect(x, y, 75, txtHeight);  
00963 #ifdef USE_LOCAL_WIDGETS
00964   NS_NewTextWidget(&mStopAfterTxt);
00965 #else
00966   CallCreateInstance(kTextFieldCID, &mStopAfterTxt);
00967 #endif
00968   NS_CreateTextWidget(mRobotDialog,mStopAfterTxt,rect,HandleRobotEvent,&font);
00969   if (mStopAfterTxt && NS_OK == mStopAfterTxt->QueryInterface(kIWidgetIID,(void**)&widget))
00970   {
00971     widget->SetBackgroundColor(textBGColor);
00972     widget->SetForegroundColor(textFGColor);
00973     mStopAfterTxt->SetText(NS_ConvertASCIItoUCS2("5000"),size);
00974   }
00975   x += 75 + 2;
00976 
00977   w = 75;
00978   rect.SetRect(x, y+4, w, 24);  
00979 #ifdef USE_LOCAL_WIDGETS
00980   NS_NewLabel(&label);
00981 #else
00982   CallCreateInstance(kLabelCID, &label);
00983 #endif
00984   NS_CreateLabel(mRobotDialog,label,rect,HandleRobotEvent,&font);
00985   label->SetAlignment(eAlign_Left);
00986   label->SetLabel(NS_ConvertASCIItoUCS2("(page loads)"));
00987   y += txtHeight + 2;
00988   
00989 
00990   y += 10;
00991   w = 75;
00992   nscoord xx = (dialogWidth - (2*w)) / 3;
00993   // Create Find Start Button
00994   rect.SetRect(xx, y, w, 24);  
00995 #ifdef USE_LOCAL_WIDGETS
00996   NS_NewButton(&mStartBtn);
00997 #else
00998   CallCreateInstance(kButtonCID, &mStartBtn);
00999 #endif
01000   NS_CreateButton(mRobotDialog,mStartBtn,rect,HandleRobotEvent,&font);
01001   mStartBtn->SetLabel(NS_ConvertASCIItoUCS2("Start"));
01002   
01003   xx += w + xx;
01004   // Create Cancel Button
01005   rect.SetRect(xx, y, w, 24);  
01006 #ifdef USE_LOCAL_WIDGETS
01007   NS_NewButton(&mCancelBtn);
01008 #else
01009   CallCreateInstance(kButtonCID, &mCancelBtn);
01010 #endif
01011   NS_CreateButton(mRobotDialog,mCancelBtn,rect,HandleRobotEvent,&font);
01012   mCancelBtn->SetLabel(NS_ConvertASCIItoUCS2("Cancel"));
01013   
01014   NS_ShowWidget(mRobotDialog,PR_TRUE);
01015   NS_SetFocusToWidget(mStartBtn);
01016   return result;
01017 }
01018 
01019 
01020 NS_IMETHODIMP
01021 nsViewerApp::CreateRobot(nsBrowserWindow* aWindow)
01022 {
01023   if (CreateRobotDialog(aWindow->mWindow))
01024   {
01025     nsIPresShell* shell = aWindow->GetPresShell();
01026     if (nsnull != shell) {
01027       nsIDocument *doc = shell->GetDocument();
01028       if (doc) {
01029         nsCAutoString str;
01030         nsresult rv = doc->GetDocumentURI()->GetSpec(str);
01031         if (NS_FAILED(rv)) {
01032           return rv;
01033         }
01034         nsVoidArray * gWorkList = new nsVoidArray();
01035 
01036         {
01037           nsString* tempStr = new nsString;
01038           if ( tempStr )
01039             CopyUTF8toUTF16(str, *tempStr);
01040           gWorkList->AppendElement(tempStr);
01041         }
01042 #if defined(XP_WIN) && defined(NS_DEBUG)
01043         DebugRobot( 
01044           gWorkList, 
01045           gVisualDebug ? aWindow->mDocShell : nsnull, 
01046           gDebugRobotLoads, 
01047           PL_strdup(gVerifyDir),
01048           yieldProc);
01049 #endif
01050       }
01051     }
01052   }
01053   return NS_OK;
01054 }
01055 
01056 
01057 //----------------------------------------
01058 static nsBrowserWindow* gWinData;
01059 static int gTop100Pointer = 0;
01060 static int gTop100LastPointer = 0;
01061 static const char *const gTop100List[] = {
01062    "http://www.yahoo.com",
01063    "http://www.netscape.com",
01064    "http://www.mozilla.org",
01065    "http://www.microsoft.com",
01066    "http://www.excite.com",
01067    "http://www.mckinley.com",
01068    "http://www.city.net",
01069    "http://www.webcrawler.com",
01070    "http://www.mirabilis.com",
01071    "http://www.infoseek.com",
01072    "http://www.warnerbros.com",
01073    "http://www.cnn.com",
01074    "http://www.altavista.com",
01075    "http://www.usatoday.com",
01076    "http://www.disney.com",
01077    "http://www.starwave.com",
01078    "http://www.hotwired.com",
01079    "http://www.hotbot.com",
01080    "http://www.amazon.com",
01081    "http://www.intel.com",
01082    "http://www.mp3.com",
01083    "http://www.ebay.com",
01084    "http://www.msn.com",
01085    "http://www.lycos.com",
01086    "http://www.pointcast.com",
01087    "http://www.cnet.com",
01088    "http://www.search.com",
01089    "http://www.news.com",
01090    "http://www.download.com",
01091    "http://www.geocities.com",
01092    "http://www.aol.com",
01093    "http://members.aol.com",
01094    "http://www.imdb.com",
01095    "http://uk.imdb.com",
01096    "http://www.macromedia.com",
01097    "http://www.infobeat.com",
01098    "http://www.fxweb.com",
01099    "http://www.whowhere.com",
01100    "http://www.real.com",
01101    "http://www.sportsline.com",
01102    "http://www.dejanews.com",
01103    "http://www.cmpnet.com",
01104    "http://www.go2net.com",
01105    "http://www.metacrawler.com",
01106    "http://www.playsite.com",
01107    "http://www.stocksite.com",
01108    "http://www.sony.com",
01109    "http://www.music.sony.com",
01110    "http://www.station.sony.com",
01111    "http://www.scea.sony.com",
01112    "http://www.infospace.com",
01113    "http://www.zdnet.com",
01114    "http://www.hotfiles.com",
01115    "http://www.chathouse.com",
01116    "http://www.looksmart.com",
01117    "http://www.imaginegames.com",
01118    "http://www.rsac.org",
01119    "http://www.apple.com",
01120    "http://www.beseen.com",
01121    "http://www.dogpile.com",
01122    "http://www.xoom.com",
01123    "http://www.tucows.com",
01124    "http://www.freethemes.com",
01125    "http://www.winfiles.com",
01126    "http://www.vservers.com",
01127    "http://www.mtv.com",
01128    "http://www.the-xfiles.com",
01129    "http://www.datek.com",
01130    "http://www.cyberthrill.com",
01131    "http://www.surplusdirect.com",
01132    "http://www.tomshardware.com",
01133    "http://www.bigyellow.com",
01134    "http://www.100hot.com",
01135    "http://www.messagemates.com",
01136    "http://www.onelist.com",
01137    "http://www.ea.com",
01138    "http://www.bullfrog.co.uk",
01139    "http://www.travelocity.com",
01140    "http://www.ibm.com",
01141    "http://www.bigcharts.com",
01142    "http://www.davesclassics.com",
01143    "http://www.goto.com",
01144    "http://www.weather.com",
01145    "http://www.gamespot.com",
01146    "http://www.bloomberg.com",
01147    "http://www.winzip.com",
01148    "http://www.filez.com",
01149    "http://www.westwood.com",
01150    "http://www.internet.com",
01151    "http://www.cardmaster.com",
01152    "http://www.creaf.com",
01153    "http://netaddress.usa.net",
01154    "http://www.occ.com",
01155    "http://www.as.org",
01156    "http://www.drudgereport.com",
01157    "http://www.hardradio.com",
01158    "http://www.fifa.com",
01159    "http://www.attitude.com",
01160    "http://www.happypuppy.com",
01161    "http://www.gamesdomain.com",
01162    "http://www.onsale.com",
01163    "http://www.tm.com",
01164    "http://www.xlnc1.com",
01165    "http://www.greatsports.com",
01166    "http://www.discovery.com",
01167    "http://www.nai.com",
01168    "http://www.nasa.gov",
01169    "http://www.ogr.com",
01170    "http://www.warzone.com",
01171    "http://www.gamestats.com",
01172    "http://www.winamp.com",
01173    "http://java.sun.com",
01174    "http://www.hp.com",
01175    "http://www.cdnow.com",
01176    "http://www.nytimes.com",
01177    "http://www.majorleaguebaseball.com",
01178    "http://www.washingtonpost.com",
01179    "http://www.planetquake.com",
01180    "http://www.wsj.com",
01181    "http://www.slashdot.org",
01182    "http://www.adobe.com",
01183    "http://www.quicken.com",
01184    "http://www.talkcity.com",
01185    "http://www.developer.com",
01186    "http://www.mapquest.com",
01187    "http://www.bluemountain.com",
01188    "http://www.the-park.com",
01189    "http://www.pathfinder.com",
01190    "http://www.macaddict.com",
01191    0
01192    };
01193 
01194 
01199 static
01200 nsEventStatus PR_CALLBACK HandleSiteEvent(nsGUIEvent *aEvent)
01201 {
01202   nsEventStatus result = nsEventStatus_eIgnore;
01203   if (aEvent == nsnull || aEvent->widget == nsnull) {
01204     return result;
01205   }
01206 
01207   switch(aEvent->message) {
01208 
01209     case NS_MOUSE_LEFT_BUTTON_UP: {
01210       if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mSiteCancelBtn)) {
01211         NS_ShowWidget(mSiteDialog,PR_FALSE);
01212 
01213       } else if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mSiteIndexTxt)) {
01214         // no op
01215 
01216       } else {
01217 
01218         PRInt32 oldIndex = gTop100Pointer;
01219 
01220         if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mSitePrevBtn)) {
01221           gTop100Pointer--;
01222         } else if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mSiteNextBtn)) {
01223           gTop100Pointer++;
01224         } else {
01225           nsString str;
01226           PRUint32 size;
01227           PRInt32  inx;
01228 
01229           mSiteIndexTxt->GetText(str, 255, size);
01230           char * cStr = ToNewCString(str);
01231           sscanf(cStr, "%d", &inx);
01232           if (inx >= 0 && inx < gTop100LastPointer) {
01233             gTop100Pointer = inx;
01234           }
01235           delete[] cStr;
01236         }
01237 
01238         PRBool loadPage = PR_FALSE;
01239         if (gTop100Pointer < 0) {
01240           gTop100Pointer = 0;
01241         } else if (gTop100Pointer >= gTop100LastPointer) {
01242           gTop100Pointer = gTop100LastPointer-1;
01243         } else {
01244           loadPage = PR_TRUE;
01245         }
01246 
01247         NS_EnableWidget(mSitePrevBtn, gTop100Pointer > 0);
01248         NS_EnableWidget(mSiteNextBtn, gTop100Pointer < (gTop100LastPointer-1));
01249 
01250         if (gWinData && loadPage && oldIndex != gTop100Pointer) {
01251           nsString urlStr; urlStr.AssignWithConversion(gTop100List[gTop100Pointer]);
01252           mSiteLabel->SetLabel(urlStr);
01253           gWinData->GoTo(urlStr.get());
01254         }
01255 
01256         nsAutoString str;
01257         str.AppendInt(gTop100Pointer);
01258         PRUint32 size;
01259         mSiteIndexTxt->SetText(str, size);
01260       }
01261       } break;
01262       
01263       case NS_PAINT: 
01264 #ifndef XP_UNIX
01265         // paint the background
01266         if (aEvent->widget->GetNativeData(NS_NATIVE_WIDGET) == GetWidgetNativeData(mSiteDialog) ) {
01267             nsIRenderingContext *drawCtx = ((nsPaintEvent*)aEvent)->renderingContext;
01268             drawCtx->SetColor(aEvent->widget->GetBackgroundColor());
01269             drawCtx->FillRect(*(((nsPaintEvent*)aEvent)->rect));
01270 
01271             return nsEventStatus_eIgnore;
01272         }
01273 #endif
01274       break;
01275 
01276       default:
01277         result = nsEventStatus_eIgnore;
01278     }
01279 
01280     return result;
01281 }
01282 
01283 //-----------------------------------------
01284 //--
01285 //-----------------------------------------
01286 static
01287 PRBool CreateSiteDialog(nsIWidget * aParent)
01288 {
01289   // Dynamically find the index of the last pointer
01290   gTop100LastPointer = 0;
01291   const char * p;
01292   do {
01293     p = gTop100List[gTop100LastPointer++];
01294   } while (p);
01295   gTop100LastPointer--;
01296 
01297   PRBool result = PR_TRUE;
01298 
01299   if (mSiteDialog == nsnull) {
01300 
01301     nsILabel * label;
01302 
01303     nsIDeviceContext* dc = aParent->GetDeviceContext();
01304     float t2d;
01305     t2d = dc->TwipsToDevUnits();
01306     nsFont font(DIALOG_FONT, NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL,
01307                 NS_FONT_WEIGHT_NORMAL, 0,
01308                 nscoord(t2d * NSIntPointsToTwips(DIALOG_FONT_SIZE)));
01309     NS_RELEASE(dc);
01310 
01311     nscoord dialogWidth = 375;
01312     // create a Dialog
01313     //
01314     nsRect rect;
01315     rect.SetRect(0, 0, dialogWidth, 125+24+10);  
01316 
01317     nsIWidget* widget = nsnull;
01318     CallCreateInstance(kWindowCID, &mSiteDialog);
01319     if (nsnull == mSiteDialog)
01320       return PR_FALSE;
01321     
01322     if (NS_OK == mSiteDialog->QueryInterface(kIWidgetIID,(void**)&widget))
01323     {
01324       widget->Create((nsIWidget *) nsnull, rect, HandleSiteEvent, NULL);
01325       //mSiteDialog->SetLabel("Top 100 Site Walker");
01326     }
01327     //mSiteDialog->SetClientData(this);
01328     nsAutoString titleStr(NS_LITERAL_STRING("Top "));
01329     titleStr.AppendInt(gTop100LastPointer);
01330     titleStr.AppendLiteral(" Sites");
01331     mSiteDialog->SetTitle(titleStr);
01332 
01333     nscoord w  = 65;
01334     nscoord x  = 5;
01335     nscoord y  = 10;
01336 
01337     // Create Label
01338     w = 50;
01339     rect.SetRect(x, y+3, w, 24);  
01340 #ifdef USE_LOCAL_WIDGETS
01341     NS_NewLabel(&label);
01342 #else
01343     CallCreateInstance(kLabelCID, &label);
01344 #endif
01345     NS_CreateLabel(mSiteDialog,label,rect,HandleSiteEvent,&font);
01346     label->SetAlignment(eAlign_Right);
01347     label->SetLabel(NS_ConvertASCIItoUCS2("Site:"));
01348     x += w + 1;
01349 
01350     w = 250;
01351     rect.SetRect(x, y+3, w, 24);  
01352 #ifdef USE_LOCAL_WIDGETS
01353     NS_NewLabel(&mSiteLabel);
01354 #else
01355    CallCreateInstance(kLabelCID, &mSiteLabel);
01356 #endif
01357     NS_CreateLabel(mSiteDialog,mSiteLabel,rect,HandleSiteEvent,&font);
01358     mSiteLabel->SetAlignment(eAlign_Left);
01359     mSiteLabel->SetLabel(EmptyString());
01360 
01361     y += 34;
01362     w = 75;
01363     nscoord spacing = (dialogWidth - (3*w)) / 4;
01364     x = spacing;
01365     // Create Previous Button
01366     rect.SetRect(x, y, w, 24);  
01367 #ifdef USE_LOCAL_WIDGETS
01368     NS_NewButton(&mSitePrevBtn);
01369 #else
01370     CallCreateInstance(kButtonCID, &mSitePrevBtn);
01371 #endif
01372     NS_CreateButton(mSiteDialog,mSitePrevBtn,rect,HandleSiteEvent,&font);
01373     mSitePrevBtn->SetLabel(NS_ConvertASCIItoUCS2("<< Previous"));
01374     x += spacing + w;
01375 
01376     // Create Next Button
01377     rect.SetRect(x, y, w, 24);  
01378 #ifdef USE_LOCAL_WIDGETS
01379     NS_NewButton(&mSiteNextBtn);
01380 #else
01381     CallCreateInstance(kButtonCID, &mSiteNextBtn);
01382 #endif
01383     NS_CreateButton(mSiteDialog,mSiteNextBtn,rect,HandleSiteEvent,&font);
01384     mSiteNextBtn->SetLabel(NS_ConvertASCIItoUCS2("Next >>"));
01385     x += spacing + w;
01386   
01387     // Create Cancel Button
01388     rect.SetRect(x, y, w, 24);  
01389 #ifdef USE_LOCAL_WIDGETS
01390     NS_NewButton(&mSiteCancelBtn);
01391 #else
01392     CallCreateInstance(kButtonCID, &mSiteCancelBtn);
01393 #endif
01394     NS_CreateButton(mSiteDialog,mSiteCancelBtn,rect,HandleSiteEvent,&font);
01395     mSiteCancelBtn->SetLabel(NS_ConvertASCIItoUCS2("Cancel"));
01396 
01398     w  = 65;
01399     x  = spacing;
01400     y  += 24 + 10;
01401 
01402     nscoord txtHeight   = 24;
01403     nscolor textBGColor = NS_RGB(255,255,255);
01404     nscolor textFGColor = NS_RGB(255,255,255);
01405 
01406     {
01407       nsCOMPtr<nsILookAndFeel> lookAndFeel = do_GetService(kLookAndFeelCID);
01408       if (lookAndFeel) {
01409         lookAndFeel->GetMetric(nsILookAndFeel::eMetric_TextFieldHeight, txtHeight);
01410         lookAndFeel->GetColor(nsILookAndFeel::eColor_TextBackground, textBGColor);
01411         lookAndFeel->GetColor(nsILookAndFeel::eColor_TextForeground, textFGColor);
01412       }
01413     }
01414 
01415     // Create TextField
01416     rect.SetRect(x, y, w, txtHeight);  
01417 #ifdef USE_LOCAL_WIDGETS
01418     NS_NewTextWidget(&mSiteIndexTxt);
01419 #else
01420     CallCreateInstance(kTextFieldCID, &mSiteIndexTxt);
01421 #endif
01422     NS_CreateTextWidget(mSiteDialog,mSiteIndexTxt,rect,HandleSiteEvent,&font);
01423     if (mVerDirTxt && NS_OK == mSiteIndexTxt->QueryInterface(kIWidgetIID,(void**)&widget)) {
01424       widget->SetBackgroundColor(textBGColor);
01425       widget->SetForegroundColor(textFGColor);
01426     }
01427 
01428     nsString str;
01429     str.AppendInt(0);
01430     PRUint32 size;
01431     mSiteIndexTxt->SetText(str,size);
01432 
01433     x += spacing + w;
01434     w = 100;
01435     // Create Jump Button
01436     rect.SetRect(x, y, w, 24);  
01437 #ifdef USE_LOCAL_WIDGETS
01438     NS_NewButton(&mSiteJumpBtn);
01439 #else
01440     CallCreateInstance(kButtonCID, &mSiteJumpBtn);
01441 #endif
01442     NS_CreateButton(mSiteDialog,mSiteJumpBtn,rect,HandleSiteEvent,&font);
01443     mSiteJumpBtn->SetLabel(NS_ConvertASCIItoUCS2("Jump to Index"));
01444   }
01445 
01446 
01447   NS_ShowWidget(mSiteDialog,PR_TRUE);
01448   NS_SetFocusToWidget(mSiteNextBtn);
01449 
01450   // Init
01451   NS_EnableWidget(mSitePrevBtn,PR_FALSE);
01452  
01453   if (gWinData) {
01454     nsString urlStr; urlStr.AssignWithConversion(gTop100List[gTop100Pointer]);
01455     gWinData->GoTo(urlStr.get());
01456     mSiteLabel->SetLabel(urlStr);
01457   }
01458 
01459   return result;
01460 }
01461 
01462 
01463 NS_IMETHODIMP
01464 nsViewerApp::CreateSiteWalker(nsBrowserWindow* aWindow)
01465 {
01466   if (nsnull == gWinData) {
01467     gWinData = aWindow;
01468     NS_ADDREF(aWindow);
01469   }
01470   CreateSiteDialog(aWindow->mWindow);
01471   return NS_OK;
01472 }
01473 
01474 //----------------------------------------
01475 
01476 
01477 #ifdef XP_WIN
01478 #include "jsconsres.h"
01479 
01480 static void DestroyConsole()
01481 {
01482  if (gConsole) {
01483     gConsole->SetNotification(NULL);
01484     delete gConsole;
01485     gConsole = NULL;
01486   }
01487 }
01488 
01489 static void ShowConsole(nsBrowserWindow* aWindow)
01490 {
01491     HWND hWnd = (HWND)aWindow->mWindow->GetNativeData(NS_NATIVE_WIDGET);
01492     if (!gConsole) {
01493 
01494       // load the accelerator table for the console
01495       if (!JSConsole::sAccelTable) {
01496         JSConsole::sAccelTable = LoadAccelerators(gInstance,
01497                                                   MAKEINTRESOURCE(ACCELERATOR_TABLE));
01498       }
01499       
01500       nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(do_GetInterface(aWindow->mDocShell));
01501       if (scriptGlobal) {
01502         nsIScriptContext *context;
01503         if ((context = scriptGlobal->GetContext())) {
01504 
01505           // create the console
01506           gConsole = JSConsole::CreateConsole();
01507           gConsole->SetContext(context);
01508           gConsole->SetNotification(DestroyConsole);
01509         }
01510       }
01511       else {
01512         MessageBox(hWnd, "Unable to load JavaScript", "Viewer Error", MB_ICONSTOP);
01513       }
01514     }
01515 }
01516 #endif
01517 
01518 NS_IMETHODIMP
01519 nsViewerApp::CreateJSConsole(nsBrowserWindow* aWindow)
01520 {
01521 #ifdef XP_WIN
01522   if (nsnull == gConsole) {
01523     ShowConsole(aWindow);
01524   }
01525 #endif
01526   return NS_OK;
01527 }
01528 
01529 NS_IMETHODIMP
01530 nsViewerApp::DoPrefs(nsBrowserWindow* aWindow)
01531 {
01532 #if defined(XP_WIN) && defined(NGPREFS)
01533 
01534   INGLayoutPrefs *pPrefs;
01535   CoInitialize(NULL);
01536 
01537   HRESULT res = CoCreateInstance(CLSID_NGLayoutPrefs, NULL, 
01538                                  CLSCTX_INPROC_SERVER,
01539                                  IID_INGLayoutPrefs, (void**)&pPrefs);
01540 
01541   if (SUCCEEDED(res)) {
01542       pPrefs->Show(NULL);
01543       pPrefs->Release();
01544   }
01545   CoUninitialize();
01546 #endif
01547   return NS_OK;
01548 }