KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > browser > Mozilla


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.browser;
12
13 import java.io.*;
14 import java.lang.reflect.*;
15 import java.util.*;
16 import org.eclipse.swt.*;
17 import org.eclipse.swt.widgets.*;
18 import org.eclipse.swt.graphics.*;
19 import org.eclipse.swt.internal.*;
20 import org.eclipse.swt.internal.mozilla.*;
21 import org.eclipse.swt.layout.*;
22
23 class Mozilla extends WebBrowser {
24     int /*long*/ embedHandle;
25     nsIWebBrowser webBrowser;
26     Object JavaDoc webBrowserObject;
27     MozillaDelegate delegate;
28
29     /* Interfaces for this Mozilla embedding notification */
30     XPCOMObject supports;
31     XPCOMObject weakReference;
32     XPCOMObject webProgressListener;
33     XPCOMObject webBrowserChrome;
34     XPCOMObject webBrowserChromeFocus;
35     XPCOMObject embeddingSiteWindow;
36     XPCOMObject interfaceRequestor;
37     XPCOMObject supportsWeakReference;
38     XPCOMObject contextMenuListener;
39     XPCOMObject uriContentListener;
40     XPCOMObject tooltipListener;
41     XPCOMObject domEventListener;
42     int chromeFlags = nsIWebBrowserChrome.CHROME_DEFAULT;
43     int refCount = 0;
44     int /*long*/ request;
45     Point location, size;
46     byte[] htmlBytes;
47     boolean visible, isChild, ignoreDispose;
48     Shell tip = null;
49     Listener listener;
50     Vector unhookedDOMWindows = new Vector ();
51
52     static nsIAppShell AppShell;
53     static AppFileLocProvider LocationProvider;
54     static WindowCreator2 WindowCreator;
55     static int BrowserCount;
56     static boolean Initialized, IsXULRunner, Is_1_8;
57
58     /* XULRunner detect constants */
59     static final String JavaDoc GRERANGE_LOWER = "1.8.1.2"; //$NON-NLS-1$
60
static final String JavaDoc GRERANGE_LOWER_FALLBACK = "1.8"; //$NON-NLS-1$
61
static final boolean LowerRangeInclusive = true;
62     static final String JavaDoc GRERANGE_UPPER = "1.9"; //$NON-NLS-1$
63
static final boolean UpperRangeInclusive = false;
64
65     static final String JavaDoc SEPARATOR_OS = System.getProperty ("file.separator"); //$NON-NLS-1$
66
static final String JavaDoc URI_FROMMEMORY = "file:///"; //$NON-NLS-1$
67
static final String JavaDoc ABOUT_BLANK = "about:blank"; //$NON-NLS-1$
68
static final String JavaDoc PREFERENCE_DISABLEOPENDURINGLOAD = "dom.disable_open_during_load"; //$NON-NLS-1$
69
static final String JavaDoc PREFERENCE_DISABLEWINDOWSTATUSCHANGE = "dom.disable_window_status_change"; //$NON-NLS-1$
70
static final String JavaDoc PREFERENCE_LANGUAGES = "intl.accept_languages"; //$NON-NLS-1$
71
static final String JavaDoc PREFERENCE_CHARSET = "intl.charset.default"; //$NON-NLS-1$
72
static final String JavaDoc SEPARATOR_LOCALE = "-"; //$NON-NLS-1$
73
static final String JavaDoc TOKENIZER_LOCALE = ","; //$NON-NLS-1$
74
static final String JavaDoc PROFILE_DIR = SEPARATOR_OS + "eclipse" + SEPARATOR_OS; //$NON-NLS-1$
75
static final String JavaDoc PROFILE_AFTER_CHANGE = "profile-after-change"; //$NON-NLS-1$
76
static final String JavaDoc PROFILE_BEFORE_CHANGE = "profile-before-change"; //$NON-NLS-1$
77
static final String JavaDoc PROFILE_DO_CHANGE = "profile-do-change"; //$NON-NLS-1$
78
static final String JavaDoc SHUTDOWN_PERSIST = "shutdown-persist"; //$NON-NLS-1$
79
static final String JavaDoc STARTUP = "startup"; //$NON-NLS-1$
80

81     // TEMPORARY CODE
82
static final String JavaDoc XULRUNNER_INITIALIZED = "org.eclipse.swt.browser.XULRunnerInitialized"; //$NON-NLS-1$
83
static final String JavaDoc XULRUNNER_PATH = "org.eclipse.swt.browser.XULRunnerPath"; //$NON-NLS-1$
84

85     static {
86         MozillaClearSessions = new Runnable JavaDoc () {
87             public void run () {
88                 if (!Initialized) return;
89                 int /*long*/[] result = new int /*long*/[1];
90                 int rc = XPCOM.NS_GetServiceManager (result);
91                 if (rc != XPCOM.NS_OK) error (rc);
92                 if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
93                 nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
94                 result[0] = 0;
95                 byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIEMANAGER_CONTRACTID, true);
96                 rc = serviceManager.GetServiceByContractID (aContractID, nsICookieManager.NS_ICOOKIEMANAGER_IID, result);
97                 if (rc != XPCOM.NS_OK) error (rc);
98                 if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
99                 serviceManager.Release ();
100
101                 nsICookieManager manager = new nsICookieManager (result[0]);
102                 result[0] = 0;
103                 rc = manager.GetEnumerator (result);
104                 if (rc != XPCOM.NS_OK) error (rc);
105                 manager.Release ();
106
107                 nsISimpleEnumerator enumerator = new nsISimpleEnumerator (result[0]);
108                 boolean[] moreElements = new boolean[1];
109                 rc = enumerator.HasMoreElements (moreElements);
110                 if (rc != XPCOM.NS_OK) error (rc);
111                 while (moreElements[0]) {
112                     result[0] = 0;
113                     rc = enumerator.GetNext (result);
114                     if (rc != XPCOM.NS_OK) error (rc);
115                     nsICookie cookie = new nsICookie (result[0]);
116                     long[] expires = new long[1];
117                     rc = cookie.GetExpires (expires);
118                     if (expires[0] == 0) {
119                         /* indicates a session cookie */
120                         int /*long*/ domain = XPCOM.nsEmbedCString_new ();
121                         int /*long*/ name = XPCOM.nsEmbedCString_new ();
122                         int /*long*/ path = XPCOM.nsEmbedCString_new ();
123                         cookie.GetHost (domain);
124                         cookie.GetName (name);
125                         cookie.GetPath (path);
126                         rc = manager.Remove (domain, name, path, false);
127                         XPCOM.nsEmbedCString_delete (domain);
128                         XPCOM.nsEmbedCString_delete (name);
129                         XPCOM.nsEmbedCString_delete (path);
130                         if (rc != XPCOM.NS_OK) error (rc);
131                     }
132                     cookie.Release ();
133                     rc = enumerator.HasMoreElements (moreElements);
134                     if (rc != XPCOM.NS_OK) error (rc);
135                 }
136                 enumerator.Release ();
137             }
138         };
139     }
140
141 public void create (Composite parent, int style) {
142     delegate = new MozillaDelegate (browser);
143     Display display = parent.getDisplay ();
144
145     int /*long*/[] result = new int /*long*/[1];
146     if (!Initialized) {
147         boolean initLoaded = false;
148         IsXULRunner = false;
149         String JavaDoc mozillaPath = System.getProperty (XULRUNNER_PATH);
150         if (mozillaPath == null) {
151             try {
152                 Library.loadLibrary ("swt-xpcominit"); //$NON-NLS-1$
153
initLoaded = true;
154             } catch (UnsatisfiedLinkError JavaDoc e) {
155                 /*
156                 * If this library failed to load then do not attempt to detect a
157                 * xulrunner to use. The Browser may still be usable if MOZILLA_FIVE_HOME
158                 * points at a GRE.
159                 */

160             }
161         } else {
162             mozillaPath += SEPARATOR_OS + delegate.getLibraryName ();
163             String JavaDoc xulrunnerInitialized = System.getProperty (XULRUNNER_INITIALIZED);
164             if ("true".equals (xulrunnerInitialized)) {
165                 /*
166                  * Another browser has already initialized xulrunner in this process,
167                  * so just bind to it instead of trying to initialize a new one.
168                  */

169                 Initialized = true;
170             }
171             IsXULRunner = true;
172         }
173
174         if (initLoaded) {
175             /* attempt to discover a XULRunner to use as the GRE */
176             GREVersionRange range = new GREVersionRange ();
177             byte[] bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER, true);
178             int /*long*/ lower = C.malloc (bytes.length);
179             C.memmove (lower, bytes, bytes.length);
180             range.lower = lower;
181             range.lowerInclusive = LowerRangeInclusive;
182
183             bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_UPPER, true);
184             int /*long*/ upper = C.malloc (bytes.length);
185             C.memmove (upper, bytes, bytes.length);
186             range.upper = upper;
187             range.upperInclusive = UpperRangeInclusive;
188
189             int length = XPCOMInit.PATH_MAX;
190             int /*long*/ greBuffer = C.malloc (length);
191             int /*long*/ propertiesPtr = C.malloc (2 * C.PTR_SIZEOF);
192             int rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length);
193
194             /*
195              * A XULRunner was not found that supports wrapping of XPCOM handles as JavaXPCOM objects.
196              * Drop the lower version bound and try to detect an earlier XULRunner installation.
197              */

198             if (rc != XPCOM.NS_OK) {
199                 C.free (lower);
200                 bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER_FALLBACK, true);
201                 lower = C.malloc (bytes.length);
202                 C.memmove (lower, bytes, bytes.length);
203                 range.lower = lower;
204                 rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length);
205             }
206
207             C.free (lower);
208             C.free (upper);
209             C.free (propertiesPtr);
210             if (rc == XPCOM.NS_OK) {
211                 /* indicates that a XULRunner was found */
212                 length = C.strlen (greBuffer);
213                 bytes = new byte[length];
214                 C.memmove (bytes, greBuffer, length);
215                 mozillaPath = new String JavaDoc (MozillaDelegate.mbcsToWcs (null, bytes));
216                 IsXULRunner = mozillaPath.length () > 0;
217
218                 /*
219                  * Test whether the detected XULRunner can be used as the GRE before loading swt's
220                  * XULRunner library. If it cannot be used then fall back to attempting to use
221                  * the GRE pointed to by MOZILLA_FIVE_HOME.
222                  *
223                  * One case where this will fail is attempting to use a 64-bit xulrunner while swt
224                  * is running in 32-bit mode, or vice versa.
225                  */

226                 if (IsXULRunner) {
227                     byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true);
228                     rc = XPCOMInit.XPCOMGlueStartup (path);
229                     if (rc != XPCOM.NS_OK) {
230                         IsXULRunner = false; /* failed */
231                         mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS));
232                         if (Device.DEBUG) System.out.println ("cannot use detected XULRunner: " + mozillaPath); //$NON-NLS-1$
233
} else {
234                         XPCOMInit.XPCOMGlueShutdown ();
235                     }
236                 }
237             }
238             C.free (greBuffer);
239         }
240
241         if (IsXULRunner) {
242             if (Device.DEBUG) System.out.println ("XULRunner path: " + mozillaPath); //$NON-NLS-1$
243
try {
244                 Library.loadLibrary ("swt-xulrunner"); //$NON-NLS-1$
245
} catch (UnsatisfiedLinkError JavaDoc e) {
246                 try {
247                     /*
248                      * The initial loadLibrary attempt may have failed as a result of the user's
249                      * system not having libstdc++.so.6 installed, so try to load the alternate
250                      * swt xulrunner library that depends on libswtc++.so.5 instead.
251                      */

252                     Library.loadLibrary ("swt-xulrunner-gcc3"); //$NON-NLS-1$
253
} catch (UnsatisfiedLinkError JavaDoc ex) {
254                     browser.dispose ();
255                     /*
256                      * Print the error from the first failed attempt since at this point it's
257                      * known that the failure was not due to the libstdc++.so.6 dependency.
258                      */

259                     SWT.error (SWT.ERROR_NO_HANDLES, e);
260                 }
261             }
262             byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true);
263             int rc = XPCOM.XPCOMGlueStartup (path);
264             if (rc != XPCOM.NS_OK) {
265                 browser.dispose ();
266                 error (rc);
267             }
268
269             /*
270              * Remove the trailing xpcom lib name from mozillaPath because the
271              * Mozilla.initialize and NS_InitXPCOM2 invocations require a directory name only.
272              */

273             mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS));
274         } else {
275             if ((style & SWT.MOZILLA) != 0) {
276                 browser.dispose ();
277                 String JavaDoc errorString = (mozillaPath != null && mozillaPath.length () > 0) ?
278                     " [Failed to use detected XULRunner: " + mozillaPath + "]" :
279                     " [Could not detect registered XULRunner to use]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
280
SWT.error (SWT.ERROR_NO_HANDLES, null, errorString);
281             }
282
283             /* attempt to use the GRE pointed at by MOZILLA_FIVE_HOME */
284             int /*long*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, XPCOM.MOZILLA_FIVE_HOME, true));
285             if (ptr != 0) {
286                 int length = C.strlen (ptr);
287                 byte[] buffer = new byte[length];
288                 C.memmove (buffer, ptr, length);
289                 mozillaPath = new String JavaDoc (MozillaDelegate.mbcsToWcs (null, buffer));
290             } else {
291                 browser.dispose ();
292                 SWT.error (SWT.ERROR_NO_HANDLES, null, " [Unknown Mozilla path (MOZILLA_FIVE_HOME not set)]"); //$NON-NLS-1$
293
}
294             if (Device.DEBUG) System.out.println ("Mozilla path: " + mozillaPath); //$NON-NLS-1$
295

296             /*
297             * Note. Embedding a Mozilla GTK1.2 causes a crash. The workaround
298             * is to check the version of GTK used by Mozilla by looking for
299             * the libwidget_gtk.so library used by Mozilla GTK1.2. Mozilla GTK2
300             * uses the libwidget_gtk2.so library.
301             */

302             File file = new File (mozillaPath, "components/libwidget_gtk.so"); //$NON-NLS-1$
303
if (file.exists ()) {
304                 browser.dispose ();
305                 SWT.error (SWT.ERROR_NO_HANDLES, null, " [Mozilla GTK2 required (GTK1.2 detected)]"); //$NON-NLS-1$
306
}
307     
308             try {
309                 Library.loadLibrary ("swt-mozilla"); //$NON-NLS-1$
310
} catch (UnsatisfiedLinkError JavaDoc e) {
311                 try {
312                     /*
313                      * The initial loadLibrary attempt may have failed as a result of the user's
314                      * system not having libstdc++.so.6 installed, so try to load the alternate
315                      * swt mozilla library that depends on libswtc++.so.5 instead.
316                      */

317                     Library.loadLibrary ("swt-mozilla-gcc3"); //$NON-NLS-1$
318
} catch (UnsatisfiedLinkError JavaDoc ex) {
319                     browser.dispose ();
320                     /*
321                      * Print the error from the first failed attempt since at this point it's
322                      * known that the failure was not due to the libstdc++.so.6 dependency.
323                      */

324                     SWT.error (SWT.ERROR_NO_HANDLES, e);
325                 }
326             }
327         }
328
329         if (!Initialized) {
330             int /*long*/[] retVal = new int /*long*/[1];
331             nsEmbedString pathString = new nsEmbedString (mozillaPath);
332             int rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), true, retVal);
333             pathString.dispose ();
334             if (rc != XPCOM.NS_OK) {
335                 browser.dispose ();
336                 error (rc);
337             }
338             if (retVal[0] == 0) {
339                 browser.dispose ();
340                 error (XPCOM.NS_ERROR_NULL_POINTER);
341             }
342
343             LocationProvider = new AppFileLocProvider (mozillaPath);
344             LocationProvider.AddRef ();
345
346             nsIFile localFile = new nsILocalFile (retVal[0]);
347             rc = XPCOM.NS_InitXPCOM2 (0, localFile.getAddress(), LocationProvider.getAddress ());
348             localFile.Release ();
349             if (rc != XPCOM.NS_OK) {
350                 browser.dispose ();
351                 SWT.error (SWT.ERROR_NO_HANDLES, null, " [MOZILLA_FIVE_HOME may not point at an embeddable GRE] [NS_InitEmbedding " + mozillaPath + " error " + rc + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
352
}
353             System.setProperty (XULRUNNER_PATH, mozillaPath);
354             System.setProperty (XULRUNNER_INITIALIZED, "true"); //$NON-NLS-1$
355
}
356
357         /* If JavaXPCOM is detected then attempt to initialize it with the XULRunner being used */
358         if (IsXULRunner) {
359             try {
360                 Class JavaDoc clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$
361
Method method = clazz.getMethod ("getInstance", new Class JavaDoc[0]); //$NON-NLS-1$
362
Object JavaDoc mozilla = method.invoke (null, new Object JavaDoc[0]);
363                 method = clazz.getMethod ("getComponentManager", new Class JavaDoc[0]); //$NON-NLS-1$
364
try {
365                     method.invoke (mozilla, new Object JavaDoc[0]);
366                 } catch (InvocationTargetException e) {
367                     /* indicates that JavaXPCOM has not been initialized yet */
368                     method = clazz.getMethod ("initialize", new Class JavaDoc[] {File.class}); //$NON-NLS-1$
369
method.invoke (mozilla, new Object JavaDoc[] {new File (mozillaPath)});
370                 }
371             } catch (ClassNotFoundException JavaDoc e) {
372                 /* JavaXPCOM is not on the classpath */
373             } catch (NoSuchMethodException JavaDoc e) {
374                 /* the JavaXPCOM on the classpath does not implement initialize() */
375             } catch (IllegalArgumentException JavaDoc e) {
376             } catch (IllegalAccessException JavaDoc e) {
377             } catch (InvocationTargetException e) {
378             }
379         }
380
381         int rc = XPCOM.NS_GetComponentManager (result);
382         if (rc != XPCOM.NS_OK) {
383             browser.dispose ();
384             error (rc);
385         }
386         if (result[0] == 0) {
387             browser.dispose ();
388             error (XPCOM.NS_NOINTERFACE);
389         }
390         
391         nsIComponentManager componentManager = new nsIComponentManager (result[0]);
392         result[0] = 0;
393         /* nsIAppShell is discontinued as of xulrunner 1.9, so do not fail if it is not found */
394         rc = componentManager.CreateInstance (XPCOM.NS_APPSHELL_CID, 0, nsIAppShell.NS_IAPPSHELL_IID, result);
395         if (rc != XPCOM.NS_ERROR_NO_INTERFACE) {
396             if (rc != XPCOM.NS_OK) {
397                 browser.dispose ();
398                 error (rc);
399             }
400             if (result[0] == 0) {
401                 browser.dispose ();
402                 error (XPCOM.NS_NOINTERFACE);
403             }
404
405             AppShell = new nsIAppShell (result[0]);
406             rc = AppShell.Create (0, null);
407             if (rc != XPCOM.NS_OK) {
408                 browser.dispose ();
409                 error (rc);
410             }
411             rc = AppShell.Spinup ();
412             if (rc != XPCOM.NS_OK) {
413                 browser.dispose ();
414                 error (rc);
415             }
416         }
417         result[0] = 0;
418
419         WindowCreator = new WindowCreator2 ();
420         WindowCreator.AddRef ();
421         
422         rc = XPCOM.NS_GetServiceManager (result);
423         if (rc != XPCOM.NS_OK) {
424             browser.dispose ();
425             error (rc);
426         }
427         if (result[0] == 0) {
428             browser.dispose ();
429             error (XPCOM.NS_NOINTERFACE);
430         }
431         
432         nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
433         result[0] = 0;
434         byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true);
435         rc = serviceManager.GetServiceByContractID (aContractID, nsIWindowWatcher.NS_IWINDOWWATCHER_IID, result);
436         if (rc != XPCOM.NS_OK) {
437             browser.dispose ();
438             error (rc);
439         }
440         if (result[0] == 0) {
441             browser.dispose ();
442             error (XPCOM.NS_NOINTERFACE);
443         }
444
445         nsIWindowWatcher windowWatcher = new nsIWindowWatcher (result[0]);
446         result[0] = 0;
447         rc = windowWatcher.SetWindowCreator (WindowCreator.getAddress());
448         if (rc != XPCOM.NS_OK) {
449             browser.dispose ();
450             error (rc);
451         }
452         windowWatcher.Release ();
453
454         /* compute the profile directory and set it on the AppFileLocProvider */
455         if (LocationProvider != null) {
456             byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DIRECTORYSERVICE_CONTRACTID, true);
457             rc = serviceManager.GetServiceByContractID (buffer, nsIDirectoryService.NS_IDIRECTORYSERVICE_IID, result);
458             if (rc != XPCOM.NS_OK) {
459                 browser.dispose ();
460                 error (rc);
461             }
462             if (result[0] == 0) {
463                 browser.dispose ();
464                 error (XPCOM.NS_NOINTERFACE);
465             }
466
467             nsIDirectoryService directoryService = new nsIDirectoryService (result[0]);
468             result[0] = 0;
469             rc = directoryService.QueryInterface (nsIProperties.NS_IPROPERTIES_IID, result);
470             if (rc != XPCOM.NS_OK) {
471                 browser.dispose ();
472                 error (rc);
473             }
474             if (result[0] == 0) {
475                 browser.dispose ();
476                 error (XPCOM.NS_NOINTERFACE);
477             }
478             directoryService.Release ();
479
480             nsIProperties properties = new nsIProperties (result[0]);
481             result[0] = 0;
482             buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_APP_APPLICATION_REGISTRY_DIR, true);
483             rc = properties.Get (buffer, nsIFile.NS_IFILE_IID, result);
484             if (rc != XPCOM.NS_OK) {
485                 browser.dispose ();
486                 error (rc);
487             }
488             if (result[0] == 0) {
489                 browser.dispose ();
490                 error (XPCOM.NS_NOINTERFACE);
491             }
492             properties.Release ();
493
494             nsIFile profileDir = new nsIFile (result[0]);
495             result[0] = 0;
496             int /*long*/ path = XPCOM.nsEmbedCString_new ();
497             rc = profileDir.GetNativePath (path);
498             if (rc != XPCOM.NS_OK) {
499                 browser.dispose ();
500                 error (rc);
501             }
502             int length = XPCOM.nsEmbedCString_Length (path);
503             int /*long*/ ptr = XPCOM.nsEmbedCString_get (path);
504             buffer = new byte [length];
505             XPCOM.memmove (buffer, ptr, length);
506             String JavaDoc profilePath = new String JavaDoc (MozillaDelegate.mbcsToWcs (null, buffer)) + PROFILE_DIR;
507             LocationProvider.setProfilePath (profilePath);
508             XPCOM.nsEmbedCString_delete (path);
509             profileDir.Release ();
510
511             /* notify observers of a new profile directory being used */
512             buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true);
513             rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result);
514             if (rc != XPCOM.NS_OK) {
515                 browser.dispose ();
516                 error (rc);
517             }
518             if (result[0] == 0) {
519                 browser.dispose ();
520                 error (XPCOM.NS_NOINTERFACE);
521             }
522
523             nsIObserverService observerService = new nsIObserverService (result[0]);
524             result[0] = 0;
525             buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_DO_CHANGE, true);
526             length = STARTUP.length ();
527             char[] chars = new char [length + 1];
528             STARTUP.getChars (0, length, chars, 0);
529             rc = observerService.NotifyObservers (0, buffer, chars);
530             if (rc != XPCOM.NS_OK) {
531                 browser.dispose ();
532                 error (rc);
533             }
534             buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_AFTER_CHANGE, true);
535             rc = observerService.NotifyObservers (0, buffer, chars);
536             if (rc != XPCOM.NS_OK) {
537                 browser.dispose ();
538                 error (rc);
539             }
540             observerService.Release ();
541
542             display.addListener (SWT.Dispose, new Listener () {
543                 public void handleEvent (Event event) {
544                     int /*long*/[] result = new int /*long*/[1];
545                     int rc = XPCOM.NS_GetServiceManager (result);
546                     if (rc != XPCOM.NS_OK) error (rc);
547                     if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
548
549                     nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
550                     result[0] = 0;
551                     byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true);
552                     rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result);
553                     if (rc != XPCOM.NS_OK) error (rc);
554                     if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
555                     serviceManager.Release ();
556
557                     nsIObserverService observerService = new nsIObserverService (result[0]);
558                     result[0] = 0;
559                     buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_BEFORE_CHANGE, true);
560                     int length = SHUTDOWN_PERSIST.length ();
561                     char[] chars = new char [length + 1];
562                     SHUTDOWN_PERSIST.getChars (0, length, chars, 0);
563                     rc = observerService.NotifyObservers (0, buffer, chars);
564                     if (rc != XPCOM.NS_OK) error (rc);
565                     observerService.Release ();
566                 }
567             });
568         }
569
570         /*
571          * As a result of using a common profile the user cannot change their locale
572          * and charset. The fix for this is to set mozilla's locale and charset
573          * preference values according to the user's current locale and charset.
574          */

575         aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true);
576         rc = serviceManager.GetServiceByContractID (aContractID, nsIPrefService.NS_IPREFSERVICE_IID, result);
577         serviceManager.Release ();
578         if (rc != XPCOM.NS_OK) {
579             browser.dispose ();
580             error (rc);
581         }
582         if (result[0] == 0) {
583             browser.dispose ();
584             error (XPCOM.NS_NOINTERFACE);
585         }
586
587         nsIPrefService prefService = new nsIPrefService (result[0]);
588         result[0] = 0;
589         byte[] buffer = new byte[1];
590         rc = prefService.GetBranch (buffer, result); /* empty buffer denotes root preference level */
591         prefService.Release ();
592         if (rc != XPCOM.NS_OK) {
593             browser.dispose ();
594             error (rc);
595         }
596         if (result[0] == 0) {
597             browser.dispose ();
598             error (XPCOM.NS_NOINTERFACE);
599         }
600
601         nsIPrefBranch prefBranch = new nsIPrefBranch (result[0]);
602         result[0] = 0;
603
604         /* get Mozilla's current locale preference value */
605         String JavaDoc prefLocales = null;
606         nsIPrefLocalizedString localizedString = null;
607         buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_LANGUAGES, true);
608         rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
609         /*
610          * Feature of Debian. For some reason attempting to query for the current locale
611          * preference fails on Debian. The workaround for this is to assume a value of
612          * "en-us,en" since this is typically the default value when mozilla is used without
613          * a profile.
614          */

615         if (rc != XPCOM.NS_OK) {
616             prefLocales = "en-us,en" + TOKENIZER_LOCALE; //$NON-NLS-1$
617
} else {
618             if (result[0] == 0) {
619                 browser.dispose ();
620                 error (XPCOM.NS_NOINTERFACE);
621             }
622             localizedString = new nsIPrefLocalizedString (result[0]);
623             result[0] = 0;
624             rc = localizedString.ToString (result);
625             if (rc != XPCOM.NS_OK) {
626                 browser.dispose ();
627                 error (rc);
628             }
629             if (result[0] == 0) {
630                 browser.dispose ();
631                 error (XPCOM.NS_NOINTERFACE);
632             }
633             int length = XPCOM.strlen_PRUnichar (result[0]);
634             char[] dest = new char[length];
635             XPCOM.memmove (dest, result[0], length * 2);
636             prefLocales = new String JavaDoc (dest) + TOKENIZER_LOCALE;
637         }
638         result[0] = 0;
639
640         /*
641          * construct the new locale preference value by prepending the
642          * user's current locale and language to the original value
643          */

644         Locale locale = Locale.getDefault ();
645         String JavaDoc language = locale.getLanguage ();
646         String JavaDoc country = locale.getCountry ();
647         StringBuffer JavaDoc stringBuffer = new StringBuffer JavaDoc (language);
648         stringBuffer.append (SEPARATOR_LOCALE);
649         stringBuffer.append (country.toLowerCase ());
650         stringBuffer.append (TOKENIZER_LOCALE);
651         stringBuffer.append (language);
652         stringBuffer.append (TOKENIZER_LOCALE);
653         String JavaDoc newLocales = stringBuffer.toString ();
654         StringTokenizer tokenzier = new StringTokenizer (prefLocales, TOKENIZER_LOCALE);
655         while (tokenzier.hasMoreTokens ()) {
656             String JavaDoc token = (tokenzier.nextToken () + TOKENIZER_LOCALE).trim ();
657             /* ensure that duplicate locale values are not added */
658             if (newLocales.indexOf (token) == -1) {
659                 stringBuffer.append (token);
660             }
661         }
662         newLocales = stringBuffer.toString ();
663         if (!newLocales.equals (prefLocales)) {
664             /* write the new locale value */
665             newLocales = newLocales.substring (0, newLocales.length () - TOKENIZER_LOCALE.length ()); /* remove trailing tokenizer */
666             int length = newLocales.length ();
667             char[] charBuffer = new char[length + 1];
668             newLocales.getChars (0, length, charBuffer, 0);
669             if (localizedString == null) {
670                 byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true);
671                 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
672                 if (rc != XPCOM.NS_OK) {
673                     browser.dispose ();
674                     error (rc);
675                 }
676                 if (result[0] == 0) {
677                     browser.dispose ();
678                     error (XPCOM.NS_NOINTERFACE);
679                 }
680                 localizedString = new nsIPrefLocalizedString (result[0]);
681                 result[0] = 0;
682             }
683             localizedString.SetDataWithLength (length, charBuffer);
684             rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress());
685         }
686         if (localizedString != null) {
687             localizedString.Release ();
688             localizedString = null;
689         }
690
691         /* get Mozilla's current charset preference value */
692         String JavaDoc prefCharset = null;
693         buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_CHARSET, true);
694         rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
695         /*
696          * Feature of Debian. For some reason attempting to query for the current charset
697          * preference fails on Debian. The workaround for this is to assume a value of
698          * "ISO-8859-1" since this is typically the default value when mozilla is used
699          * without a profile.
700          */

701         if (rc != XPCOM.NS_OK) {
702             prefCharset = "ISO-8859-1"; //$NON_NLS-1$
703
} else {
704             if (result[0] == 0) {
705                 browser.dispose ();
706                 error (XPCOM.NS_NOINTERFACE);
707             }
708             localizedString = new nsIPrefLocalizedString (result[0]);
709             result[0] = 0;
710             rc = localizedString.ToString (result);
711             if (rc != XPCOM.NS_OK) {
712                 browser.dispose ();
713                 error (rc);
714             }
715             if (result[0] == 0) {
716                 browser.dispose ();
717                 error (XPCOM.NS_NOINTERFACE);
718             }
719             int length = XPCOM.strlen_PRUnichar (result[0]);
720             char[] dest = new char[length];
721             XPCOM.memmove (dest, result[0], length * 2);
722             prefCharset = new String JavaDoc (dest);
723         }
724         result[0] = 0;
725
726         String JavaDoc newCharset = System.getProperty ("file.encoding"); // $NON-NLS-1$
727
if (!newCharset.equals (prefCharset)) {
728             /* write the new charset value */
729             int length = newCharset.length ();
730             char[] charBuffer = new char[length + 1];
731             newCharset.getChars (0, length, charBuffer, 0);
732             if (localizedString == null) {
733                 byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true);
734                 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result);
735                 if (rc != XPCOM.NS_OK) {
736                     browser.dispose ();
737                     error (rc);
738                 }
739                 if (result[0] == 0) {
740                     browser.dispose ();
741                     error (XPCOM.NS_NOINTERFACE);
742                 }
743                 localizedString = new nsIPrefLocalizedString (result[0]);
744                 result[0] = 0;
745             }
746             localizedString.SetDataWithLength (length, charBuffer);
747             rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ());
748         }
749         if (localizedString != null) localizedString.Release ();
750
751         /*
752         * Ensure that windows that are shown during page loads are not blocked. Firefox may
753         * try to block these by default since such windows are often unwelcome, but this
754         * assumption should not be made in the Browser's context. Since the Browser client
755         * is responsible for creating the new Browser and Shell in an OpenWindowListener,
756         * they should decide whether the new window is unwelcome or not and act accordingly.
757         */

758         buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEOPENDURINGLOAD, true);
759         rc = prefBranch.SetBoolPref (buffer, 0);
760         if (rc != XPCOM.NS_OK) {
761             browser.dispose ();
762             error (rc);
763         }
764
765         /* Ensure that the status text can be set through means like javascript */
766         buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEWINDOWSTATUSCHANGE, true);
767         rc = prefBranch.SetBoolPref (buffer, 0);
768         if (rc != XPCOM.NS_OK) {
769             browser.dispose ();
770             error (rc);
771         }
772
773         prefBranch.Release ();
774
775         PromptServiceFactory factory = new PromptServiceFactory ();
776         factory.AddRef ();
777
778         rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result);
779         if (rc != XPCOM.NS_OK) {
780             browser.dispose ();
781             error (rc);
782         }
783         if (result[0] == 0) {
784             browser.dispose ();
785             error (XPCOM.NS_NOINTERFACE);
786         }
787         
788         nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]);
789         result[0] = 0;
790         aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PROMPTSERVICE_CONTRACTID, true);
791         byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "Prompt Service", true); //$NON-NLS-1$
792
rc = componentRegistrar.RegisterFactory (XPCOM.NS_PROMPTSERVICE_CID, aClassName, aContractID, factory.getAddress ());
793         if (rc != XPCOM.NS_OK) {
794             browser.dispose ();
795             error (rc);
796         }
797         factory.Release ();
798         
799         HelperAppLauncherDialogFactory dialogFactory = new HelperAppLauncherDialogFactory ();
800         dialogFactory.AddRef ();
801         aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CONTRACTID, true);
802         aClassName = MozillaDelegate.wcsToMbcs (null, "Helper App Launcher Dialog", true); //$NON-NLS-1$
803
rc = componentRegistrar.RegisterFactory (XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CID, aClassName, aContractID, dialogFactory.getAddress ());
804         if (rc != XPCOM.NS_OK) {
805             browser.dispose ();
806             error (rc);
807         }
808         dialogFactory.Release ();
809
810         DownloadFactory downloadFactory = new DownloadFactory ();
811         downloadFactory.AddRef ();
812         aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOWNLOAD_CONTRACTID, true);
813         aClassName = MozillaDelegate.wcsToMbcs (null, "Download", true); //$NON-NLS-1$
814
rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory.getAddress ());
815         if (rc != XPCOM.NS_OK) {
816             browser.dispose ();
817             error (rc);
818         }
819         downloadFactory.Release ();
820
821         DownloadFactory_1_8 downloadFactory_1_8 = new DownloadFactory_1_8 ();
822         downloadFactory_1_8.AddRef ();
823         aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_TRANSFER_CONTRACTID, true);
824         aClassName = MozillaDelegate.wcsToMbcs (null, "Transfer", true); //$NON-NLS-1$
825
rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory_1_8.getAddress ());
826         if (rc != XPCOM.NS_OK) {
827             browser.dispose ();
828             error (rc);
829         }
830         downloadFactory_1_8.Release ();
831
832         FilePickerFactory pickerFactory = IsXULRunner ? new FilePickerFactory_1_8 () : new FilePickerFactory ();
833         pickerFactory.AddRef ();
834         aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_FILEPICKER_CONTRACTID, true);
835         aClassName = MozillaDelegate.wcsToMbcs (null, "FilePicker", true); //$NON-NLS-1$
836
rc = componentRegistrar.RegisterFactory (XPCOM.NS_FILEPICKER_CID, aClassName, aContractID, pickerFactory.getAddress ());
837         if (rc != XPCOM.NS_OK) {
838             browser.dispose ();
839             error (rc);
840         }
841         pickerFactory.Release ();
842
843         componentRegistrar.Release ();
844         componentManager.Release ();
845         Is_1_8 = IsXULRunner;
846         Initialized = true;
847     }
848
849     BrowserCount++;
850     int rc = XPCOM.NS_GetComponentManager (result);
851     if (rc != XPCOM.NS_OK) {
852         browser.dispose ();
853         error (rc);
854     }
855     if (result[0] == 0) {
856         browser.dispose ();
857         error (XPCOM.NS_NOINTERFACE);
858     }
859     
860     nsIComponentManager componentManager = new nsIComponentManager (result[0]);
861     result[0] = 0;
862     nsID NS_IWEBBROWSER_CID = new nsID ("F1EAC761-87E9-11d3-AF80-00A024FFC08C"); //$NON-NLS-1$
863
rc = componentManager.CreateInstance (NS_IWEBBROWSER_CID, 0, nsIWebBrowser.NS_IWEBBROWSER_IID, result);
864     if (rc != XPCOM.NS_OK) {
865         browser.dispose ();
866         error (rc);
867     }
868     if (result[0] == 0) {
869         browser.dispose ();
870         error (XPCOM.NS_NOINTERFACE);
871     }
872     componentManager.Release ();
873     
874     webBrowser = new nsIWebBrowser (result[0]);
875     result[0] = 0;
876
877     createCOMInterfaces ();
878     AddRef ();
879
880     if (!Is_1_8) {
881         /*
882         * Check for the availability of frozen interface nsIWebBrowserStream to determine if the
883         * GRE's version is >= 1.8.
884         */

885         rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result);
886         if (rc == XPCOM.NS_OK && result[0] != 0) {
887             Is_1_8 = true;
888             new nsISupports (result[0]).Release ();
889             result[0] = 0;
890         }
891     }
892
893     rc = webBrowser.SetContainerWindow (webBrowserChrome.getAddress());
894     if (rc != XPCOM.NS_OK) {
895         browser.dispose ();
896         error (rc);
897     }
898             
899     rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
900     if (rc != XPCOM.NS_OK) {
901         browser.dispose ();
902         error (rc);
903     }
904     if (result[0] == 0) {
905         browser.dispose ();
906         error (XPCOM.NS_ERROR_NO_INTERFACE);
907     }
908     
909     nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
910     result[0] = 0;
911     Rectangle rect = browser.getClientArea ();
912     if (rect.isEmpty ()) {
913         rect.width = 1;
914         rect.height = 1;
915     }
916
917     embedHandle = delegate.getHandle ();
918
919     rc = baseWindow.InitWindow (embedHandle, 0, 0, 0, rect.width, rect.height);
920     if (rc != XPCOM.NS_OK) {
921         browser.dispose ();
922         error (XPCOM.NS_ERROR_FAILURE);
923     }
924     rc = baseWindow.Create ();
925     if (rc != XPCOM.NS_OK) {
926         browser.dispose ();
927         error (XPCOM.NS_ERROR_FAILURE);
928     }
929     rc = baseWindow.SetVisibility (true);
930     if (rc != XPCOM.NS_OK) {
931         browser.dispose ();
932         error (XPCOM.NS_ERROR_FAILURE);
933     }
934     baseWindow.Release ();
935
936     rc = webBrowser.AddWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID);
937     if (rc != XPCOM.NS_OK) {
938         browser.dispose ();
939         error (rc);
940     }
941
942     rc = webBrowser.SetParentURIContentListener (uriContentListener.getAddress ());
943     if (rc != XPCOM.NS_OK) {
944         browser.dispose ();
945         error (rc);
946     }
947
948     delegate.init ();
949
950     listener = new Listener () {
951         public void handleEvent (Event event) {
952             switch (event.type) {
953                 case SWT.Dispose: {
954                     /* make this handler run after other dispose listeners */
955                     if (ignoreDispose) {
956                         ignoreDispose = false;
957                         break;
958                     }
959                     ignoreDispose = true;
960                     browser.notifyListeners (event.type, event);
961                     event.type = SWT.NONE;
962                     onDispose (event.display);
963                     break;
964                 }
965                 case SWT.Resize: onResize (); break;
966                 case SWT.FocusIn: Activate (); break;
967                 case SWT.Activate: Activate (); break;
968                 case SWT.Deactivate: {
969                     Display display = event.display;
970                     if (Mozilla.this.browser == display.getFocusControl ()) Deactivate ();
971                     break;
972                 }
973                 case SWT.Show: {
974                     /*
975                     * Feature in GTK Mozilla. Mozilla does not show up when
976                     * its container (a GTK fixed handle) is made visible
977                     * after having been hidden. The workaround is to reset
978                     * its size after the container has been made visible.
979                     */

980                     Display display = event.display;
981                     display.asyncExec(new Runnable JavaDoc () {
982                         public void run() {
983                             if (browser.isDisposed ()) return;
984                             onResize ();
985                         }
986                     });
987                     break;
988                 }
989             }
990         }
991     };
992     int[] folderEvents = new int[] {
993         SWT.Dispose,
994         SWT.Resize,
995         SWT.FocusIn,
996         SWT.Activate,
997         SWT.Deactivate,
998         SWT.Show,
999         SWT.KeyDown // needed to make browser traversable
1000
};
1001    for (int i = 0; i < folderEvents.length; i++) {
1002        browser.addListener (folderEvents[i], listener);
1003    }
1004}
1005
1006public boolean back () {
1007    int /*long*/[] result = new int /*long*/[1];
1008    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1009    if (rc != XPCOM.NS_OK) error (rc);
1010    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1011    
1012    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1013    rc = webNavigation.GoBack ();
1014    webNavigation.Release ();
1015    return rc == XPCOM.NS_OK;
1016}
1017
1018void createCOMInterfaces () {
1019    // Create each of the interfaces that this object implements
1020
supports = new XPCOMObject (new int[] {2, 0, 0}) {
1021        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1022        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1023        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1024    };
1025    
1026    weakReference = new XPCOMObject (new int[] {2, 0, 0, 2}) {
1027        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1028        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1029        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1030        public int /*long*/ method3 (int /*long*/[] args) {return QueryReferent (args[0], args[1]);}
1031    };
1032
1033    webProgressListener = new XPCOMObject (new int[] {2, 0, 0, 4, 6, 3, 4, 3}) {
1034        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1035        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1036        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1037        public int /*long*/ method3 (int /*long*/[] args) {return OnStateChange (args[0], args[1], args[2],args[3]);}
1038        public int /*long*/ method4 (int /*long*/[] args) {return OnProgressChange (args[0], args[1], args[2], args[3], args[4], args[5]);}
1039        public int /*long*/ method5 (int /*long*/[] args) {return OnLocationChange (args[0], args[1], args[2]);}
1040        public int /*long*/ method6 (int /*long*/[] args) {return OnStatusChange (args[0], args[1], args[2], args[3]);}
1041        public int /*long*/ method7 (int /*long*/[] args) {return OnSecurityChange (args[0], args[1], args[2]);}
1042    };
1043    
1044    webBrowserChrome = new XPCOMObject (new int[] {2, 0, 0, 2, 1, 1, 1, 1, 0, 2, 0, 1, 1}) {
1045        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1046        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1047        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1048        public int /*long*/ method3 (int /*long*/[] args) {return SetStatus (args[0], args[1]);}
1049        public int /*long*/ method4 (int /*long*/[] args) {return GetWebBrowser (args[0]);}
1050        public int /*long*/ method5 (int /*long*/[] args) {return SetWebBrowser (args[0]);}
1051        public int /*long*/ method6 (int /*long*/[] args) {return GetChromeFlags (args[0]);}
1052        public int /*long*/ method7 (int /*long*/[] args) {return SetChromeFlags (args[0]);}
1053        public int /*long*/ method8 (int /*long*/[] args) {return DestroyBrowserWindow ();}
1054        public int /*long*/ method9 (int /*long*/[] args) {return SizeBrowserTo (args[0], args[1]);}
1055        public int /*long*/ method10 (int /*long*/[] args) {return ShowAsModal ();}
1056        public int /*long*/ method11 (int /*long*/[] args) {return IsWindowModal (args[0]);}
1057        public int /*long*/ method12 (int /*long*/[] args) {return ExitModalEventLoop (args[0]);}
1058    };
1059    
1060    webBrowserChromeFocus = new XPCOMObject (new int[] {2, 0, 0, 0, 0}) {
1061        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1062        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1063        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1064        public int /*long*/ method3 (int /*long*/[] args) {return FocusNextElement ();}
1065        public int /*long*/ method4 (int /*long*/[] args) {return FocusPrevElement ();}
1066    };
1067        
1068    embeddingSiteWindow = new XPCOMObject (new int[] {2, 0, 0, 5, 5, 0, 1, 1, 1, 1, 1}) {
1069        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1070        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1071        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1072        public int /*long*/ method3 (int /*long*/[] args) {return SetDimensions (args[0], args[1], args[2], args[3], args[4]);}
1073        public int /*long*/ method4 (int /*long*/[] args) {return GetDimensions (args[0], args[1], args[2], args[3], args[4]);}
1074        public int /*long*/ method5 (int /*long*/[] args) {return SetFocus ();}
1075        public int /*long*/ method6 (int /*long*/[] args) {return GetVisibility (args[0]);}
1076        public int /*long*/ method7 (int /*long*/[] args) {return SetVisibility (args[0]);}
1077        public int /*long*/ method8 (int /*long*/[] args) {return GetTitle (args[0]);}
1078        public int /*long*/ method9 (int /*long*/[] args) {return SetTitle (args[0]);}
1079        public int /*long*/ method10 (int /*long*/[] args) {return GetSiteWindow (args[0]);}
1080    };
1081    
1082    interfaceRequestor = new XPCOMObject (new int[] {2, 0, 0, 2} ){
1083        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1084        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1085        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1086        public int /*long*/ method3 (int /*long*/[] args) {return GetInterface (args[0], args[1]);}
1087    };
1088        
1089    supportsWeakReference = new XPCOMObject (new int[] {2, 0, 0, 1}) {
1090        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1091        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1092        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1093        public int /*long*/ method3 (int /*long*/[] args) {return GetWeakReference (args[0]);}
1094    };
1095    
1096    contextMenuListener = new XPCOMObject (new int[] {2, 0, 0, 3}) {
1097        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1098        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1099        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1100        public int /*long*/ method3 (int /*long*/[] args) {return OnShowContextMenu (args[0],args[1],args[2]);}
1101    };
1102    
1103    uriContentListener = new XPCOMObject (new int[] {2, 0, 0, 2, 5, 3, 4, 1, 1, 1, 1}) {
1104        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1105        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1106        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1107        public int /*long*/ method3 (int /*long*/[] args) {return OnStartURIOpen (args[0], args[1]);}
1108        public int /*long*/ method4 (int /*long*/[] args) {return DoContent (args[0], args[1], args[2], args[3], args[4]);}
1109        public int /*long*/ method5 (int /*long*/[] args) {return IsPreferred (args[0], args[1], args[2]);}
1110        public int /*long*/ method6 (int /*long*/[] args) {return CanHandleContent (args[0], args[1], args[2], args[3]);}
1111        public int /*long*/ method7 (int /*long*/[] args) {return GetLoadCookie (args[0]);}
1112        public int /*long*/ method8 (int /*long*/[] args) {return SetLoadCookie (args[0]);}
1113        public int /*long*/ method9 (int /*long*/[] args) {return GetParentContentListener (args[0]);}
1114        public int /*long*/ method10 (int /*long*/[] args) {return SetParentContentListener (args[0]);}
1115    };
1116    
1117    tooltipListener = new XPCOMObject (new int[] {2, 0, 0, 3, 0}) {
1118        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1119        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1120        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1121        public int /*long*/ method3 (int /*long*/[] args) {return OnShowTooltip (args[0], args[1], args[2]);}
1122        public int /*long*/ method4 (int /*long*/[] args) {return OnHideTooltip ();}
1123    };
1124
1125    domEventListener = new XPCOMObject (new int[] {2, 0, 0, 1}) {
1126        public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);}
1127        public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();}
1128        public int /*long*/ method2 (int /*long*/[] args) {return Release ();}
1129        public int /*long*/ method3 (int /*long*/[] args) {return HandleEvent (args[0]);}
1130    };
1131}
1132
1133void disposeCOMInterfaces () {
1134    if (supports != null) {
1135        supports.dispose ();
1136        supports = null;
1137    }
1138    if (weakReference != null) {
1139        weakReference.dispose ();
1140        weakReference = null;
1141    }
1142    if (webProgressListener != null) {
1143        webProgressListener.dispose ();
1144        webProgressListener = null;
1145    }
1146    if (webBrowserChrome != null) {
1147        webBrowserChrome.dispose ();
1148        webBrowserChrome = null;
1149    }
1150    if (webBrowserChromeFocus != null) {
1151        webBrowserChromeFocus.dispose ();
1152        webBrowserChromeFocus = null;
1153    }
1154    if (embeddingSiteWindow != null) {
1155        embeddingSiteWindow.dispose ();
1156        embeddingSiteWindow = null;
1157    }
1158    if (interfaceRequestor != null) {
1159        interfaceRequestor.dispose ();
1160        interfaceRequestor = null;
1161    }
1162    if (supportsWeakReference != null) {
1163        supportsWeakReference.dispose ();
1164        supportsWeakReference = null;
1165    }
1166    if (contextMenuListener != null) {
1167        contextMenuListener.dispose ();
1168        contextMenuListener = null;
1169    }
1170    if (uriContentListener != null) {
1171        uriContentListener.dispose ();
1172        uriContentListener = null;
1173    }
1174    if (tooltipListener != null) {
1175        tooltipListener.dispose ();
1176        tooltipListener = null;
1177    }
1178}
1179
1180public boolean execute (String JavaDoc script) {
1181    String JavaDoc url = "javascript:" + script + ";void(0);"; //$NON-NLS-1$ //$NON-NLS-2$
1182
int /*long*/[] result = new int /*long*/[1];
1183    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1184    if (rc != XPCOM.NS_OK) error (rc);
1185    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1186
1187    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1188    char[] arg = url.toCharArray ();
1189    char[] c = new char[arg.length+1];
1190    System.arraycopy (arg, 0, c, 0, arg.length);
1191    rc = webNavigation.LoadURI (c, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
1192    webNavigation.Release ();
1193    return rc == XPCOM.NS_OK;
1194}
1195
1196static Browser findBrowser (int /*long*/ handle) {
1197    return MozillaDelegate.findBrowser (handle);
1198}
1199
1200public boolean forward () {
1201    int /*long*/[] result = new int /*long*/[1];
1202    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1203    if (rc != XPCOM.NS_OK) error (rc);
1204    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1205    
1206    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1207    rc = webNavigation.GoForward ();
1208    webNavigation.Release ();
1209
1210    return rc == XPCOM.NS_OK;
1211}
1212
1213public String JavaDoc getUrl () {
1214    int /*long*/[] result = new int /*long*/[1];
1215    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1216    if (rc != XPCOM.NS_OK) error (rc);
1217    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1218
1219    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1220    int /*long*/[] aCurrentURI = new int /*long*/[1];
1221    rc = webNavigation.GetCurrentURI (aCurrentURI);
1222    if (rc != XPCOM.NS_OK) error (rc);
1223    webNavigation.Release ();
1224
1225    byte[] dest = null;
1226    if (aCurrentURI[0] != 0) {
1227        nsIURI uri = new nsIURI (aCurrentURI[0]);
1228        int /*long*/ aSpec = XPCOM.nsEmbedCString_new ();
1229        rc = uri.GetSpec (aSpec);
1230        if (rc != XPCOM.NS_OK) error (rc);
1231        int length = XPCOM.nsEmbedCString_Length (aSpec);
1232        int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec);
1233        dest = new byte[length];
1234        XPCOM.memmove (dest, buffer, length);
1235        XPCOM.nsEmbedCString_delete (aSpec);
1236        uri.Release ();
1237    }
1238    if (dest == null) return ""; //$NON-NLS-1$
1239

1240    String JavaDoc location = new String JavaDoc (dest);
1241    /*
1242     * If the URI indicates that the page is being rendered from memory
1243     * (via setText()) then set it to about:blank to be consistent with IE.
1244     */

1245    if (location.equals (URI_FROMMEMORY)) location = ABOUT_BLANK;
1246    return location;
1247}
1248
1249public Object JavaDoc getWebBrowser () {
1250    if ((browser.getStyle () & SWT.MOZILLA) == 0) return null;
1251    if (webBrowserObject != null) return webBrowserObject;
1252
1253    try {
1254        Class JavaDoc clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$
1255
Method method = clazz.getMethod ("getInstance", new Class JavaDoc[0]); //$NON-NLS-1$
1256
Object JavaDoc mozilla = method.invoke (null, new Object JavaDoc[0]);
1257        method = clazz.getMethod ("wrapXPCOMObject", new Class JavaDoc[] {Long.TYPE, String JavaDoc.class}); //$NON-NLS-1$
1258
webBrowserObject = method.invoke (mozilla, new Object JavaDoc[] {new Long JavaDoc (webBrowser.getAddress ()), nsIWebBrowser.NS_IWEBBROWSER_IID_STR});
1259        return webBrowserObject;
1260    } catch (ClassNotFoundException JavaDoc e) {
1261    } catch (NoSuchMethodException JavaDoc e) {
1262    } catch (IllegalArgumentException JavaDoc e) {
1263    } catch (IllegalAccessException JavaDoc e) {
1264    } catch (InvocationTargetException e) {
1265    }
1266    return null;
1267}
1268
1269public boolean isBackEnabled () {
1270    int /*long*/[] result = new int /*long*/[1];
1271    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1272    if (rc != XPCOM.NS_OK) error (rc);
1273    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1274    
1275    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1276    boolean[] aCanGoBack = new boolean[1];
1277    rc = webNavigation.GetCanGoBack (aCanGoBack);
1278    webNavigation.Release ();
1279    return aCanGoBack[0];
1280}
1281
1282public boolean isForwardEnabled () {
1283    int /*long*/[] result = new int /*long*/[1];
1284    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1285    if (rc != XPCOM.NS_OK) error (rc);
1286    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1287    
1288    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1289    boolean[] aCanGoForward = new boolean[1];
1290    rc = webNavigation.GetCanGoForward (aCanGoForward);
1291    webNavigation.Release ();
1292    return aCanGoForward[0];
1293}
1294
1295static String JavaDoc error (int code) {
1296    throw new SWTError ("XPCOM error " + code); //$NON-NLS-1$
1297
}
1298
1299void onDispose (Display display) {
1300    int rc = webBrowser.RemoveWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID);
1301    if (rc != XPCOM.NS_OK) error (rc);
1302
1303    rc = webBrowser.SetParentURIContentListener (0);
1304    if (rc != XPCOM.NS_OK) error (rc);
1305    
1306    unhookDOMListeners ();
1307    if (listener != null) {
1308        int[] folderEvents = new int[] {
1309            SWT.Dispose,
1310            SWT.Resize,
1311            SWT.FocusIn,
1312            SWT.Activate,
1313            SWT.Deactivate,
1314            SWT.Show,
1315            SWT.KeyDown,
1316        };
1317        for (int i = 0; i < folderEvents.length; i++) {
1318            browser.removeListener (folderEvents[i], listener);
1319        }
1320        listener = null;
1321    }
1322
1323    int /*long*/[] result = new int /*long*/[1];
1324    rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
1325    if (rc != XPCOM.NS_OK) error (rc);
1326    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1327
1328    nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
1329    rc = baseWindow.Destroy ();
1330    if (rc != XPCOM.NS_OK) error (rc);
1331    baseWindow.Release ();
1332
1333    Release ();
1334    webBrowser.Release ();
1335    webBrowser = null;
1336    webBrowserObject = null;
1337
1338    if (tip != null && !tip.isDisposed ()) tip.dispose ();
1339    tip = null;
1340    location = size = null;
1341    htmlBytes = null;
1342
1343    Enumeration elements = unhookedDOMWindows.elements ();
1344    while (elements.hasMoreElements ()) {
1345        LONG ptrObject = (LONG)elements.nextElement ();
1346        new nsISupports (ptrObject.value).Release ();
1347    }
1348    unhookedDOMWindows = null;
1349
1350    delegate.onDispose (embedHandle);
1351    delegate = null;
1352
1353    embedHandle = 0;
1354    BrowserCount--;
1355}
1356
1357void Activate () {
1358    int /*long*/[] result = new int /*long*/[1];
1359    int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result);
1360    if (rc != XPCOM.NS_OK) error (rc);
1361    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1362    
1363    nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]);
1364    rc = webBrowserFocus.Activate ();
1365    if (rc != XPCOM.NS_OK) error (rc);
1366    webBrowserFocus.Release ();
1367}
1368    
1369void Deactivate () {
1370    int /*long*/[] result = new int /*long*/[1];
1371    int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result);
1372    if (rc != XPCOM.NS_OK) error (rc);
1373    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1374    
1375    nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]);
1376    rc = webBrowserFocus.Deactivate ();
1377    if (rc != XPCOM.NS_OK) error (rc);
1378    webBrowserFocus.Release ();
1379}
1380
1381void onResize () {
1382    Rectangle rect = browser.getClientArea ();
1383    int width = Math.max (1, rect.width);
1384    int height = Math.max (1, rect.height);
1385
1386    int /*long*/[] result = new int /*long*/[1];
1387    int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
1388    if (rc != XPCOM.NS_OK) error (rc);
1389    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1390
1391    delegate.setSize (embedHandle, width, height);
1392    nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
1393    rc = baseWindow.SetPositionAndSize (0, 0, width, height, true);
1394    if (rc != XPCOM.NS_OK) error (rc);
1395    baseWindow.Release ();
1396}
1397
1398public void refresh () {
1399    int /*long*/[] result = new int /*long*/[1];
1400    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1401    if (rc != XPCOM.NS_OK) error(rc);
1402    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1403    
1404    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1405    rc = webNavigation.Reload (nsIWebNavigation.LOAD_FLAGS_NONE);
1406    webNavigation.Release ();
1407    if (rc == XPCOM.NS_OK) return;
1408    /*
1409    * Feature in Mozilla. Reload returns an error code NS_ERROR_INVALID_POINTER
1410    * when it is called immediately after a request to load a new document using
1411    * LoadURI. The workaround is to ignore this error code.
1412    *
1413    * Feature in Mozilla. Attempting to reload a file that no longer exists
1414    * returns an error code of NS_ERROR_FILE_NOT_FOUND. This is equivalent to
1415    * attempting to load a non-existent local url, which is not a Browser error,
1416    * so this error code should be ignored.
1417    */

1418    if (rc != XPCOM.NS_ERROR_INVALID_POINTER && rc != XPCOM.NS_ERROR_FILE_NOT_FOUND) error (rc);
1419}
1420
1421public boolean setText (String JavaDoc html) {
1422    /*
1423    * Feature in Mozilla. The focus memory of Mozilla must be
1424    * properly managed through the nsIWebBrowserFocus interface.
1425    * In particular, nsIWebBrowserFocus.deactivate must be called
1426    * when the focus moves from the browser (or one of its children
1427    * managed by Mozilla to another widget. We currently do not
1428    * get notified when a widget takes focus away from the Browser.
1429    * As a result, deactivate is not properly called. This causes
1430    * Mozilla to retake focus the next time a document is loaded.
1431    * This breaks the case where the HTML loaded in the Browser
1432    * varies while the user enters characters in a text widget. The text
1433    * widget loses focus every time new content is loaded.
1434    * The current workaround is to call deactivate everytime if
1435    * the browser currently does not have focus. A better workaround
1436    * would be to have a way to call deactivate when the Browser
1437    * or one of its children loses focus.
1438    */

1439    if (browser != browser.getDisplay ().getFocusControl ()) Deactivate ();
1440    
1441    /* convert the String containing HTML to an array of bytes with UTF-8 data */
1442    byte[] data = null;
1443    try {
1444        data = html.getBytes ("UTF-8"); //$NON-NLS-1$
1445
} catch (UnsupportedEncodingException e) {
1446        return false;
1447    }
1448
1449    /*
1450    * If the GRE version is >= 1.8 then use frozen interface nsIWebBrowserStream.
1451    * If this interface is not available then use the pre-1.8 approach of utilizing
1452    * nsIDocShell instead.
1453    */

1454    if (Is_1_8) {
1455        /*
1456        * Feature of nsIWebBrowserStream. Setting the browser's content directly through
1457        * its nsIWebBrowserStream does not cause a page change to occur, and therefore the
1458        * events that typically signal a page change are not fired. To make this behave
1459        * as expected, navigate to about:blank first, and then set the html content once
1460        * the page has loaded.
1461        */

1462
1463        /*
1464        * If the htmlBytes field is non-null then the about:blank page is already being
1465        * loaded, so no Navigate is required. Just set the html that is to be shown.
1466        */

1467        boolean blankLoading = htmlBytes != null;
1468        htmlBytes = data;
1469        if (blankLoading) return true;
1470
1471        /* navigate to about:blank */
1472        int /*long*/[] result = new int /*long*/[1];
1473        int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1474        if (rc != XPCOM.NS_OK) error (rc);
1475        if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1476        nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1477        result[0] = 0;
1478        char[] uri = new char[ABOUT_BLANK.length () + 1];
1479        ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uri, 0);
1480        rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
1481        if (rc != XPCOM.NS_OK) error (rc);
1482        webNavigation.Release ();
1483    } else {
1484        byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
1485
int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length);
1486        byte[] contentCharsetBuffer = MozillaDelegate.wcsToMbcs (null, "UTF-8", true); //$NON-NLS-1$
1487
int /*long*/ aContentCharset = XPCOM.nsEmbedCString_new (contentCharsetBuffer, contentCharsetBuffer.length);
1488
1489        int /*long*/[] result = new int /*long*/[1];
1490        int rc = XPCOM.NS_GetServiceManager (result);
1491        if (rc != XPCOM.NS_OK) error (rc);
1492        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1493
1494        nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
1495        result[0] = 0;
1496        rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
1497        if (rc != XPCOM.NS_OK) error (rc);
1498        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1499        serviceManager.Release ();
1500
1501        nsIIOService ioService = new nsIIOService (result[0]);
1502        result[0] = 0;
1503        /*
1504        * Note. Mozilla ignores LINK tags used to load CSS stylesheets
1505        * when the URI protocol for the nsInputStreamChannel
1506        * is about:blank. The fix is to specify the file protocol.
1507        */

1508        byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, false);
1509        int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
1510        rc = ioService.NewURI (aSpec, null, 0, result);
1511        if (rc != XPCOM.NS_OK) error (rc);
1512        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1513        XPCOM.nsEmbedCString_delete (aSpec);
1514        ioService.Release ();
1515        
1516        nsIURI uri = new nsIURI (result[0]);
1517        result[0] = 0;
1518
1519        rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result);
1520        if (rc != XPCOM.NS_OK) error (rc);
1521        if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1522
1523        nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]);
1524        result[0] = 0;
1525        rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result);
1526        if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1527        interfaceRequestor.Release ();
1528
1529        nsIDocShell docShell = new nsIDocShell (result[0]);
1530        result[0] = 0;
1531
1532        /*
1533        * Feature in Mozilla. LoadStream invokes the nsIInputStream argument
1534        * through a different thread. The callback mechanism must attach
1535        * a non java thread to the JVM otherwise the nsIInputStream Read and
1536        * Close methods never get called.
1537        */

1538        InputStream inputStream = new InputStream (data);
1539        inputStream.AddRef ();
1540        rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0);
1541        if (rc != XPCOM.NS_OK) error (rc);
1542        inputStream.Release ();
1543        docShell.Release ();
1544        uri.Release ();
1545        XPCOM.nsEmbedCString_delete (aContentCharset);
1546        XPCOM.nsEmbedCString_delete (aContentType);
1547    }
1548
1549    return true;
1550}
1551
1552public boolean setUrl (String JavaDoc url) {
1553    htmlBytes = null;
1554
1555    int /*long*/[] result = new int /*long*/[1];
1556    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1557    if (rc != XPCOM.NS_OK) error (rc);
1558    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1559
1560    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1561    char[] uri = new char[url.length () + 1];
1562    url.getChars (0, url.length (), uri, 0);
1563    rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
1564    webNavigation.Release ();
1565    return rc == XPCOM.NS_OK;
1566}
1567
1568public void stop () {
1569    int /*long*/[] result = new int /*long*/[1];
1570    int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
1571    if (rc != XPCOM.NS_OK) error (rc);
1572    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1573    
1574    nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
1575    rc = webNavigation.Stop (nsIWebNavigation.STOP_ALL);
1576    if (rc != XPCOM.NS_OK) error (rc);
1577    webNavigation.Release ();
1578}
1579
1580void hookDOMListeners () {
1581    int /*long*/[] result = new int /*long*/[1];
1582    int rc = webBrowser.GetContentDOMWindow (result);
1583    if (rc != XPCOM.NS_OK) error (rc);
1584    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1585
1586    nsIDOMWindow window = new nsIDOMWindow (result[0]);
1587    result[0] = 0;
1588    rc = window.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
1589    if (rc != XPCOM.NS_OK) error (rc);
1590    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1591
1592    nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
1593    result[0] = 0;
1594    hookDOMListeners (target, true);
1595    target.Release ();
1596
1597    /* Listeners must be hooked in pages contained in frames */
1598    rc = window.GetFrames (result);
1599    if (rc != XPCOM.NS_OK) error (rc);
1600    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1601    nsIDOMWindowCollection frames = new nsIDOMWindowCollection (result[0]);
1602    result[0] = 0;
1603    int[] frameCount = new int[1];
1604    rc = frames.GetLength (frameCount); /* PRUint32 */
1605    if (rc != XPCOM.NS_OK) error (rc);
1606    int count = frameCount[0];
1607
1608    if (count > 0) {
1609        for (int i = 0; i < count; i++) {
1610            rc = frames.Item (i, result);
1611            if (rc != XPCOM.NS_OK) error (rc);
1612            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1613
1614            nsIDOMWindow frame = new nsIDOMWindow (result[0]);
1615            result[0] = 0;
1616            rc = frame.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
1617            if (rc != XPCOM.NS_OK) error (rc);
1618            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1619
1620            target = new nsIDOMEventTarget (result[0]);
1621            result[0] = 0;
1622            hookDOMListeners (target, false);
1623            target.Release ();
1624            frame.Release ();
1625        }
1626    }
1627    frames.Release ();
1628    window.Release ();
1629}
1630
1631void hookDOMListeners (nsIDOMEventTarget target, boolean isTop) {
1632    nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS);
1633    int rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1634    if (rc != XPCOM.NS_OK) error (rc);
1635    string.dispose ();
1636    string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD);
1637    rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1638    if (rc != XPCOM.NS_OK) error (rc);
1639    string.dispose ();
1640    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN);
1641    rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1642    if (rc != XPCOM.NS_OK) error (rc);
1643    string.dispose ();
1644    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP);
1645    rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1646    if (rc != XPCOM.NS_OK) error (rc);
1647    string.dispose ();
1648    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE);
1649    rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1650    if (rc != XPCOM.NS_OK) error (rc);
1651    string.dispose ();
1652
1653    /*
1654    * Only hook mouseover and mouseout if the target is a top-level frame, so that mouse moves
1655    * between frames will not generate events.
1656    */

1657    if (isTop && delegate.hookEnterExit ()) {
1658        string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER);
1659        rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1660        if (rc != XPCOM.NS_OK) error (rc);
1661        string.dispose ();
1662        string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT);
1663        rc = target.AddEventListener (string.getAddress (), domEventListener.getAddress (), false);
1664        if (rc != XPCOM.NS_OK) error (rc);
1665        string.dispose ();
1666    }
1667}
1668
1669void unhookDOMListeners () {
1670    int /*long*/[] result = new int /*long*/[1];
1671    int rc = webBrowser.GetContentDOMWindow (result);
1672    if (rc != XPCOM.NS_OK) error (rc);
1673    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1674
1675    nsIDOMWindow window = new nsIDOMWindow (result[0]);
1676    result[0] = 0;
1677    rc = window.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
1678    if (rc != XPCOM.NS_OK) error (rc);
1679    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1680
1681    nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
1682    result[0] = 0;
1683    unhookDOMListeners (target);
1684    target.Release ();
1685
1686    /* Listeners must be unhooked in pages contained in frames */
1687    rc = window.GetFrames (result);
1688    if (rc != XPCOM.NS_OK) error (rc);
1689    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1690    nsIDOMWindowCollection frames = new nsIDOMWindowCollection (result[0]);
1691    result[0] = 0;
1692    int[] frameCount = new int[1];
1693    rc = frames.GetLength (frameCount); /* PRUint32 */
1694    if (rc != XPCOM.NS_OK) error (rc);
1695    int count = frameCount[0];
1696
1697    if (count > 0) {
1698        for (int i = 0; i < count; i++) {
1699            rc = frames.Item (i, result);
1700            if (rc != XPCOM.NS_OK) error (rc);
1701            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1702
1703            nsIDOMWindow frame = new nsIDOMWindow (result[0]);
1704            result[0] = 0;
1705            rc = frame.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
1706            if (rc != XPCOM.NS_OK) error (rc);
1707            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1708
1709            target = new nsIDOMEventTarget (result[0]);
1710            result[0] = 0;
1711            unhookDOMListeners (target);
1712            target.Release ();
1713            frame.Release ();
1714        }
1715    }
1716    frames.Release ();
1717    window.Release ();
1718}
1719
1720void unhookDOMListeners (nsIDOMEventTarget target) {
1721    nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS);
1722    int rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1723    string.dispose ();
1724    if (rc != XPCOM.NS_OK) return; /* listeners not hooked */
1725    string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD);
1726    rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1727    if (rc != XPCOM.NS_OK) error (rc);
1728    string.dispose ();
1729    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN);
1730    rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1731    if (rc != XPCOM.NS_OK) error (rc);
1732    string.dispose ();
1733    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP);
1734    rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1735    if (rc != XPCOM.NS_OK) error (rc);
1736    string.dispose ();
1737    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE);
1738    rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1739    if (rc != XPCOM.NS_OK) error (rc);
1740    string.dispose ();
1741    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER);
1742    rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1743    string.dispose ();
1744    string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT);
1745    rc = target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), false);
1746    string.dispose ();
1747}
1748
1749/* nsISupports */
1750
1751int /*long*/ QueryInterface (int /*long*/ riid, int /*long*/ ppvObject) {
1752    if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE;
1753
1754    nsID guid = new nsID ();
1755    XPCOM.memmove (guid, riid, nsID.sizeof);
1756
1757    if (guid.Equals (nsISupports.NS_ISUPPORTS_IID)) {
1758        XPCOM.memmove (ppvObject, new int /*long*/[] {supports.getAddress ()}, C.PTR_SIZEOF);
1759        AddRef ();
1760        return XPCOM.NS_OK;
1761    }
1762    if (guid.Equals (nsIWeakReference.NS_IWEAKREFERENCE_IID)) {
1763        XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF);
1764        AddRef ();
1765        return XPCOM.NS_OK;
1766    }
1767    if (guid.Equals (nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID)) {
1768        XPCOM.memmove (ppvObject, new int /*long*/[] {webProgressListener.getAddress ()}, C.PTR_SIZEOF);
1769        AddRef ();
1770        return XPCOM.NS_OK;
1771    }
1772    if (guid.Equals (nsIWebBrowserChrome.NS_IWEBBROWSERCHROME_IID)) {
1773        XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChrome.getAddress ()}, C.PTR_SIZEOF);
1774        AddRef ();
1775        return XPCOM.NS_OK;
1776    }
1777    if (guid.Equals (nsIWebBrowserChromeFocus.NS_IWEBBROWSERCHROMEFOCUS_IID)) {
1778        XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChromeFocus.getAddress ()}, C.PTR_SIZEOF);
1779        AddRef ();
1780        return XPCOM.NS_OK;
1781    }
1782    if (guid.Equals (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID)) {
1783        XPCOM.memmove (ppvObject, new int /*long*/[] {embeddingSiteWindow.getAddress ()}, C.PTR_SIZEOF);
1784        AddRef ();
1785        return XPCOM.NS_OK;
1786    }
1787    if (guid.Equals (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID)) {
1788        XPCOM.memmove (ppvObject, new int /*long*/[] {interfaceRequestor.getAddress ()}, C.PTR_SIZEOF);
1789        AddRef ();
1790        return XPCOM.NS_OK;
1791    }
1792    if (guid.Equals (nsISupportsWeakReference.NS_ISUPPORTSWEAKREFERENCE_IID)) {
1793        XPCOM.memmove (ppvObject, new int /*long*/[] {supportsWeakReference.getAddress ()}, C.PTR_SIZEOF);
1794        AddRef ();
1795        return XPCOM.NS_OK;
1796    }
1797    if (guid.Equals (nsIContextMenuListener.NS_ICONTEXTMENULISTENER_IID)) {
1798        XPCOM.memmove (ppvObject, new int /*long*/[] {contextMenuListener.getAddress ()}, C.PTR_SIZEOF);
1799        AddRef ();
1800        return XPCOM.NS_OK;
1801    }
1802    if (guid.Equals (nsIURIContentListener.NS_IURICONTENTLISTENER_IID)) {
1803        XPCOM.memmove (ppvObject, new int /*long*/[] {uriContentListener.getAddress ()}, C.PTR_SIZEOF);
1804        AddRef ();
1805        return XPCOM.NS_OK;
1806    }
1807    if (guid.Equals (nsITooltipListener.NS_ITOOLTIPLISTENER_IID)) {
1808        XPCOM.memmove (ppvObject, new int /*long*/[] {tooltipListener.getAddress ()}, C.PTR_SIZEOF);
1809        AddRef ();
1810        return XPCOM.NS_OK;
1811    }
1812    XPCOM.memmove (ppvObject, new int /*long*/[] {0}, C.PTR_SIZEOF);
1813    return XPCOM.NS_ERROR_NO_INTERFACE;
1814}
1815
1816int /*long*/ AddRef () {
1817    refCount++;
1818    return refCount;
1819}
1820
1821int /*long*/ Release () {
1822    refCount--;
1823    if (refCount == 0) disposeCOMInterfaces ();
1824    return refCount;
1825}
1826
1827/* nsIWeakReference */
1828    
1829int /*long*/ QueryReferent (int /*long*/ riid, int /*long*/ ppvObject) {
1830    return QueryInterface (riid, ppvObject);
1831}
1832
1833/* nsIInterfaceRequestor */
1834
1835int /*long*/ GetInterface (int /*long*/ riid, int /*long*/ ppvObject) {
1836    if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE;
1837    nsID guid = new nsID ();
1838    XPCOM.memmove (guid, riid, nsID.sizeof);
1839    if (guid.Equals (nsIDOMWindow.NS_IDOMWINDOW_IID)) {
1840        int /*long*/[] aContentDOMWindow = new int /*long*/[1];
1841        int rc = webBrowser.GetContentDOMWindow (aContentDOMWindow);
1842        if (rc != XPCOM.NS_OK) error (rc);
1843        if (aContentDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1844        XPCOM.memmove (ppvObject, aContentDOMWindow, C.PTR_SIZEOF);
1845        return rc;
1846    }
1847    return QueryInterface (riid, ppvObject);
1848}
1849
1850int /*long*/ GetWeakReference (int /*long*/ ppvObject) {
1851    XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF);
1852    AddRef ();
1853    return XPCOM.NS_OK;
1854}
1855
1856/* nsIWebProgressListener */
1857
1858int /*long*/ OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aStateFlags, int /*long*/ aStatus) {
1859    if ((aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) == 0) return XPCOM.NS_OK;
1860    if ((aStateFlags & nsIWebProgressListener.STATE_START) != 0) {
1861        if (request == 0) request = aRequest;
1862
1863        /*
1864         * Add the page's nsIDOMWindow to the collection of windows that will
1865         * have DOM listeners added to them later on in the page loading
1866         * process. These listeners cannot be added yet because the
1867         * nsIDOMWindow is not ready to take them at this stage.
1868         */

1869        int /*long*/[] result = new int /*long*/[1];
1870        nsIWebProgress progress = new nsIWebProgress (aWebProgress);
1871        int rc = progress.GetDOMWindow (result);
1872        if (rc != XPCOM.NS_OK) error (rc);
1873        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1874        unhookedDOMWindows.addElement (new LONG (result[0]));
1875    } else if ((aStateFlags & nsIWebProgressListener.STATE_REDIRECTING) != 0) {
1876        if (request == aRequest) request = 0;
1877    } else if ((aStateFlags & nsIWebProgressListener.STATE_STOP) != 0) {
1878        /*
1879        * If this page's nsIDOMWindow handle is still in unhookedDOMWindows then
1880        * add its DOM listeners now. It's possible for this to happen since
1881        * there is no guarantee that a STATE_TRANSFERRING state change will be
1882        * received for every window in a page, which is when these listeners
1883        * are typically added.
1884        */

1885        int /*long*/[] result = new int /*long*/[1];
1886        nsIWebProgress progress = new nsIWebProgress (aWebProgress);
1887        int rc = progress.GetDOMWindow (result);
1888        if (rc != XPCOM.NS_OK) error (rc);
1889        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1890        nsIDOMWindow domWindow = new nsIDOMWindow (result[0]);
1891
1892        LONG ptrObject = new LONG (result[0]);
1893        result[0] = 0;
1894        int index = unhookedDOMWindows.indexOf (ptrObject);
1895        if (index != -1) {
1896            rc = webBrowser.GetContentDOMWindow (result);
1897            if (rc != XPCOM.NS_OK) error (rc);
1898            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1899            boolean isTop = result[0] == domWindow.getAddress ();
1900            new nsISupports (result[0]).Release ();
1901            result[0] = 0;
1902
1903            rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
1904            if (rc != XPCOM.NS_OK) error (rc);
1905            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
1906
1907            nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
1908            result[0] = 0;
1909            hookDOMListeners (target, isTop);
1910            target.Release ();
1911
1912            /*
1913            * Remove and unreference the nsIDOMWindow from the collection of windows
1914            * that are waiting to have DOM listeners hooked on them.
1915            */

1916            unhookedDOMWindows.remove (ptrObject);
1917            new nsISupports (ptrObject.value).Release ();
1918        }
1919        domWindow.Release ();
1920
1921        /*
1922         * If htmlBytes is not null then there is html from a previous setText() call
1923         * waiting to be set into the about:blank page once it has completed loading.
1924         */

1925        if (htmlBytes != null) {
1926            nsIRequest req = new nsIRequest (aRequest);
1927            int /*long*/ name = XPCOM.nsEmbedCString_new ();
1928            rc = req.GetName (name);
1929            if (rc != XPCOM.NS_OK) error (rc);
1930            int length = XPCOM.nsEmbedCString_Length (name);
1931            int /*long*/ buffer = XPCOM.nsEmbedCString_get (name);
1932            byte[] dest = new byte[length];
1933            XPCOM.memmove (dest, buffer, length);
1934            XPCOM.nsEmbedCString_delete (name);
1935            String JavaDoc url = new String JavaDoc (dest);
1936
1937            if (url.startsWith (ABOUT_BLANK)) {
1938                /*
1939                 * Setting the browser's content with nsIWebBrowserStream invalidates the
1940                 * DOM listeners that were hooked on it (about:blank), so remove them and
1941                 * add new ones after the content has been set.
1942                 */

1943                unhookDOMListeners ();
1944
1945                rc = XPCOM.NS_GetServiceManager (result);
1946                if (rc != XPCOM.NS_OK) error (rc);
1947                if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1948
1949                nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
1950                result[0] = 0;
1951                rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
1952                if (rc != XPCOM.NS_OK) error (rc);
1953                if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1954                serviceManager.Release ();
1955
1956                nsIIOService ioService = new nsIIOService (result[0]);
1957                result[0] = 0;
1958                /*
1959                * Note. Mozilla ignores LINK tags used to load CSS stylesheets
1960                * when the URI protocol for the nsInputStreamChannel
1961                * is about:blank. The fix is to specify the file protocol.
1962                */

1963                byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, false);
1964                int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
1965                rc = ioService.NewURI (aSpec, null, 0, result);
1966                XPCOM.nsEmbedCString_delete (aSpec);
1967                if (rc != XPCOM.NS_OK) error (rc);
1968                if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1969                ioService.Release ();
1970
1971                nsIURI uri = new nsIURI (result[0]);
1972                result[0] = 0;
1973
1974                rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result);
1975                if (rc != XPCOM.NS_OK) error (rc);
1976                if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
1977                nsIWebBrowserStream stream = new nsIWebBrowserStream (result[0]);
1978                result[0] = 0;
1979
1980                byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
1981
int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length);
1982
1983                rc = stream.OpenStream (uri.getAddress (), aContentType);
1984                if (rc != XPCOM.NS_OK) error (rc);
1985                int /*long*/ ptr = C.malloc (htmlBytes.length);
1986                XPCOM.memmove (ptr, htmlBytes, htmlBytes.length);
1987                int pageSize = 8192;
1988                int pageCount = htmlBytes.length / pageSize + 1;
1989                int /*long*/ current = ptr;
1990                for (int i = 0; i < pageCount; i++) {
1991                    length = i == pageCount - 1 ? htmlBytes.length % pageSize : pageSize;
1992                    if (length > 0) {
1993                        rc = stream.AppendToStream (current, length);
1994                        if (rc != XPCOM.NS_OK) error (rc);
1995                    }
1996                    current += pageSize;
1997                }
1998                rc = stream.CloseStream ();
1999                if (rc != XPCOM.NS_OK) error (rc);
2000
2001                C.free (ptr);
2002                XPCOM.nsEmbedCString_delete (aContentType);
2003                stream.Release ();
2004                uri.Release ();
2005                htmlBytes = null;
2006                hookDOMListeners ();
2007            }
2008        }
2009
2010        /*
2011        * Feature in Mozilla. When a request is redirected (STATE_REDIRECTING),
2012        * it never reaches the state STATE_STOP and it is replaced with a new request.
2013        * The new request is received when it is in the state STATE_STOP.
2014        * To handle this case, the variable request is set to 0 when the corresponding
2015        * request is redirected. The following request received with the state STATE_STOP
2016        * - the new request resulting from the redirection - is used to send
2017        * the ProgressListener.completed event.
2018        */

2019        if (request == aRequest || request == 0) {
2020            request = 0;
2021            StatusTextEvent event = new StatusTextEvent (browser);
2022            event.display = browser.getDisplay ();
2023            event.widget = browser;
2024            event.text = ""; //$NON-NLS-1$
2025
for (int i = 0; i < statusTextListeners.length; i++) {
2026                statusTextListeners[i].changed (event);
2027            }
2028            ProgressEvent event2 = new ProgressEvent (browser);
2029            event2.display = browser.getDisplay ();
2030            event2.widget = browser;
2031            for (int i = 0; i < progressListeners.length; i++) {
2032                progressListeners[i].completed (event2);
2033            }
2034        }
2035    } else if ((aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING) != 0) {
2036        /*
2037        * Hook DOM listeners to the page's nsIDOMWindow here because this is
2038        * the earliest opportunity to do so.
2039        */

2040        int /*long*/[] result = new int /*long*/[1];
2041        nsIWebProgress progress = new nsIWebProgress (aWebProgress);
2042        int rc = progress.GetDOMWindow (result);
2043        if (rc != XPCOM.NS_OK) error (rc);
2044        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2045        nsIDOMWindow domWindow = new nsIDOMWindow (result[0]);
2046
2047        LONG ptrObject = new LONG (result[0]);
2048        result[0] = 0;
2049        int index = unhookedDOMWindows.indexOf (ptrObject);
2050        if (index != -1) {
2051            rc = webBrowser.GetContentDOMWindow (result);
2052            if (rc != XPCOM.NS_OK) error (rc);
2053            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
2054            boolean isTop = result[0] == domWindow.getAddress ();
2055            new nsISupports (result[0]).Release ();
2056            result[0] = 0;
2057
2058            rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
2059            if (rc != XPCOM.NS_OK) error (rc);
2060            if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
2061
2062            nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
2063            result[0] = 0;
2064            hookDOMListeners (target, isTop);
2065            target.Release ();
2066
2067            /*
2068            * Remove and unreference the nsIDOMWindow from the collection of windows
2069            * that are waiting to have DOM listeners hooked on them.
2070            */

2071            unhookedDOMWindows.remove (ptrObject);
2072            new nsISupports (ptrObject.value).Release ();
2073        }
2074        domWindow.Release ();
2075    }
2076    return XPCOM.NS_OK;
2077}
2078
2079int /*long*/ OnProgressChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aCurSelfProgress, int /*long*/ aMaxSelfProgress, int /*long*/ aCurTotalProgress, int /*long*/ aMaxTotalProgress) {
2080    if (progressListeners.length == 0) return XPCOM.NS_OK;
2081    ProgressEvent event = new ProgressEvent (browser);
2082    event.display = browser.getDisplay ();
2083    event.widget = browser;
2084    event.current = (int)/*64*/aCurTotalProgress;
2085    event.total = (int)/*64*/aMaxTotalProgress;
2086    for (int i = 0; i < progressListeners.length; i++) {
2087        progressListeners[i].changed (event);
2088    }
2089    return XPCOM.NS_OK;
2090}
2091
2092int /*long*/ OnLocationChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aLocation) {
2093    /*
2094    * Feature in Mozilla. When a page is loaded via setText before a previous
2095    * setText page load has completed, the expected OnStateChange STATE_STOP for the
2096    * original setText never arrives because it gets replaced by the OnStateChange
2097    * STATE_STOP for the new request. This results in the request field never being
2098    * cleared because the original request's OnStateChange STATE_STOP is still expected
2099    * (but never arrives). To handle this case, the request field is updated to the new
2100    * overriding request since its OnStateChange STATE_STOP will be received next.
2101    */

2102    if (request != 0 && request != aRequest) request = aRequest;
2103
2104    if (locationListeners.length == 0) return XPCOM.NS_OK;
2105
2106    nsIWebProgress webProgress = new nsIWebProgress (aWebProgress);
2107    int /*long*/[] aDOMWindow = new int /*long*/[1];
2108    int rc = webProgress.GetDOMWindow (aDOMWindow);
2109    if (rc != XPCOM.NS_OK) error (rc);
2110    if (aDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
2111    
2112    nsIDOMWindow domWindow = new nsIDOMWindow (aDOMWindow[0]);
2113    int /*long*/[] aTop = new int /*long*/[1];
2114    rc = domWindow.GetTop (aTop);
2115    if (rc != XPCOM.NS_OK) error (rc);
2116    if (aTop[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
2117    domWindow.Release ();
2118    
2119    nsIDOMWindow topWindow = new nsIDOMWindow (aTop[0]);
2120    topWindow.Release ();
2121    
2122    nsIURI location = new nsIURI (aLocation);
2123    int /*long*/ aSpec = XPCOM.nsEmbedCString_new ();
2124    location.GetSpec (aSpec);
2125    int length = XPCOM.nsEmbedCString_Length (aSpec);
2126    int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec);
2127    byte[] dest = new byte[length];
2128    XPCOM.memmove (dest, buffer, length);
2129    XPCOM.nsEmbedCString_delete (aSpec);
2130    String JavaDoc url = new String JavaDoc (dest);
2131
2132    /*
2133     * As of Mozilla 1.8, the first time that a page is displayed, regardless of
2134     * whether it's via Browser.setURL() or Browser.setText(), the GRE navigates
2135     * to about:blank and fires the corresponding navigation events. Do not send
2136     * this event on the user since it is not expected.
2137     */

2138    if (Is_1_8 && aRequest == 0 && url.startsWith (ABOUT_BLANK)) return XPCOM.NS_OK;
2139
2140    LocationEvent event = new LocationEvent (browser);
2141    event.display = browser.getDisplay ();
2142    event.widget = browser;
2143    event.location = url;
2144    /*
2145     * If the URI indicates that the page is being rendered from memory
2146     * (via setText()) then set it to about:blank to be consistent with IE.
2147     */

2148    if (event.location.equals (URI_FROMMEMORY)) event.location = ABOUT_BLANK;
2149    event.top = aTop[0] == aDOMWindow[0];
2150    for (int i = 0; i < locationListeners.length; i++) {
2151        locationListeners[i].changed (event);
2152    }
2153    return XPCOM.NS_OK;
2154}
2155
2156int /*long*/ OnStatusChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aStatus, int /*long*/ aMessage) {
2157    if (statusTextListeners.length == 0) return XPCOM.NS_OK;
2158    StatusTextEvent event = new StatusTextEvent (browser);
2159    event.display = browser.getDisplay ();
2160    event.widget = browser;
2161    int length = XPCOM.strlen_PRUnichar (aMessage);
2162    char[] dest = new char[length];
2163    XPCOM.memmove (dest, aMessage, length * 2);
2164    event.text = new String JavaDoc (dest);
2165    for (int i = 0; i < statusTextListeners.length; i++) {
2166        statusTextListeners[i].changed (event);
2167    }
2168    return XPCOM.NS_OK;
2169}
2170
2171int /*long*/ OnSecurityChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ state) {
2172    return XPCOM.NS_OK;
2173}
2174
2175/* nsIWebBrowserChrome */
2176
2177int /*long*/ SetStatus (int /*long*/ statusType, int /*long*/ status) {
2178    StatusTextEvent event = new StatusTextEvent (browser);
2179    event.display = browser.getDisplay ();
2180    event.widget = browser;
2181    int length = XPCOM.strlen_PRUnichar (status);
2182    char[] dest = new char[length];
2183    XPCOM.memmove (dest, status, length * 2);
2184    String JavaDoc string = new String JavaDoc (dest);
2185    event.text = string;
2186    for (int i = 0; i < statusTextListeners.length; i++) {
2187        statusTextListeners[i].changed (event);
2188    }
2189    return XPCOM.NS_OK;
2190}
2191
2192int /*long*/ GetWebBrowser (int /*long*/ aWebBrowser) {
2193    int /*long*/[] ret = new int /*long*/[1];
2194    if (webBrowser != null) {
2195        webBrowser.AddRef ();
2196        ret[0] = webBrowser.getAddress ();
2197    }
2198    XPCOM.memmove (aWebBrowser, ret, C.PTR_SIZEOF);
2199    return XPCOM.NS_OK;
2200}
2201
2202int /*long*/ SetWebBrowser (int /*long*/ aWebBrowser) {
2203    if (webBrowser != null) webBrowser.Release ();
2204    webBrowser = aWebBrowser != 0 ? new nsIWebBrowser (aWebBrowser) : null;
2205    return XPCOM.NS_OK;
2206}
2207   
2208int /*long*/ GetChromeFlags (int /*long*/ aChromeFlags) {
2209    int[] ret = new int[1];
2210    ret[0] = chromeFlags;
2211    XPCOM.memmove (aChromeFlags, ret, 4); /* PRUint32 */
2212    return XPCOM.NS_OK;
2213}
2214
2215int /*long*/ SetChromeFlags (int /*long*/ aChromeFlags) {
2216    chromeFlags = (int)/*64*/aChromeFlags;
2217    return XPCOM.NS_OK;
2218}
2219
2220int /*long*/ DestroyBrowserWindow () {
2221    WindowEvent newEvent = new WindowEvent (browser);
2222    newEvent.display = browser.getDisplay ();
2223    newEvent.widget = browser;
2224    for (int i = 0; i < closeWindowListeners.length; i++) {
2225        closeWindowListeners[i].close (newEvent);
2226    }
2227    /*
2228    * Note on Mozilla. The DestroyBrowserWindow notification cannot be cancelled.
2229    * The browser widget cannot be used after this notification has been received.
2230    * The application is advised to close the window hosting the browser widget.
2231    * The browser widget must be disposed in all cases.
2232    */

2233    browser.dispose ();
2234    return XPCOM.NS_OK;
2235}
2236    
2237int /*long*/ SizeBrowserTo (int /*long*/ aCX, int /*long*/ aCY) {
2238    size = new Point ((int)/*64*/aCX, (int)/*64*/aCY);
2239    boolean isChrome = (chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0;
2240    if (isChrome) {
2241        Shell shell = browser.getShell ();
2242        shell.setSize (shell.computeSize (size.x, size.y));
2243    }
2244    return XPCOM.NS_OK;
2245}
2246
2247int /*long*/ ShowAsModal () {
2248    int /*long*/[] result = new int /*long*/[1];
2249    int rc = XPCOM.NS_GetServiceManager (result);
2250    if (rc != XPCOM.NS_OK) error (rc);
2251    if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2252
2253    nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
2254    result[0] = 0;
2255    byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_CONTEXTSTACK_CONTRACTID, true);
2256    rc = serviceManager.GetServiceByContractID (aContractID, nsIJSContextStack.NS_IJSCONTEXTSTACK_IID, result);
2257    if (rc != XPCOM.NS_OK) error (rc);
2258    if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2259    serviceManager.Release ();
2260
2261    nsIJSContextStack stack = new nsIJSContextStack (result[0]);
2262    result[0] = 0;
2263    rc = stack.Push (0);
2264    if (rc != XPCOM.NS_OK) error (rc);
2265
2266    Shell shell = browser.getShell ();
2267    Display display = browser.getDisplay ();
2268    while (!shell.isDisposed ()) {
2269        if (!display.readAndDispatch ()) display.sleep ();
2270    }
2271
2272    rc = stack.Pop (result);
2273    if (rc != XPCOM.NS_OK) error (rc);
2274    stack.Release ();
2275    return XPCOM.NS_OK;
2276}
2277
2278int /*long*/ IsWindowModal (int /*long*/ retval) {
2279    int result = (chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) != 0 ? 1 : 0;
2280    XPCOM.memmove (retval, new int[] {result}, 4); /* PRBool */
2281    return XPCOM.NS_OK;
2282}
2283   
2284int /*long*/ ExitModalEventLoop (int /*long*/ aStatus) {
2285    return XPCOM.NS_OK;
2286}
2287
2288/* nsIEmbeddingSiteWindow */
2289
2290int /*long*/ SetDimensions (int /*long*/ flags, int /*long*/ x, int /*long*/ y, int /*long*/ cx, int /*long*/ cy) {
2291    if (flags == nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) location = new Point ((int)/*64*/x, (int)/*64*/y);
2292    return XPCOM.NS_OK;
2293}
2294
2295int /*long*/ GetDimensions (int /*long*/ flags, int /*long*/ x, int /*long*/ y, int /*long*/ cx, int /*long*/ cy) {
2296    return XPCOM.NS_OK;
2297}
2298
2299int /*long*/ SetFocus () {
2300    int /*long*/[] result = new int /*long*/[1];
2301    int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result);
2302    if (rc != XPCOM.NS_OK) error (rc);
2303    if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
2304    
2305    nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]);
2306    rc = baseWindow.SetFocus ();
2307    if (rc != XPCOM.NS_OK) error (rc);
2308    baseWindow.Release ();
2309
2310    /*
2311    * Note. Mozilla notifies here that one of the children took
2312    * focus. This could or should be used to fire an SWT.FOCUS_IN
2313    * event on Browser focus listeners.
2314    */

2315    return XPCOM.NS_OK;
2316}
2317
2318int /*long*/ GetVisibility (int /*long*/ aVisibility) {
2319    XPCOM.memmove (aVisibility, new int[] {browser.isVisible () ? 1 : 0}, 4); /* PRBool */
2320    return XPCOM.NS_OK;
2321}
2322
2323int /*long*/ SetVisibility (int /*long*/ aVisibility) {
2324    if (isChild) {
2325        WindowEvent event = new WindowEvent (browser);
2326        event.display = browser.getDisplay ();
2327        event.widget = browser;
2328        if (aVisibility == 1) {
2329            /*
2330            * Bug in Mozilla. When the JavaScript window.open is executed, Mozilla
2331            * fires multiple SetVisibility 1 notifications. The workaround is
2332            * to ignore subsequent notifications.
2333            */

2334            if (!visible) {
2335                visible = true;
2336                event.location = location;
2337                event.size = size;
2338                event.addressBar = (chromeFlags & nsIWebBrowserChrome.CHROME_LOCATIONBAR) != 0;
2339                event.menuBar = (chromeFlags & nsIWebBrowserChrome.CHROME_MENUBAR) != 0;
2340                event.statusBar = (chromeFlags & nsIWebBrowserChrome.CHROME_STATUSBAR) != 0;
2341                event.toolBar = (chromeFlags & nsIWebBrowserChrome.CHROME_TOOLBAR) != 0;
2342                for (int i = 0; i < visibilityWindowListeners.length; i++) {
2343                    visibilityWindowListeners[i].show (event);
2344                }
2345                location = null;
2346                size = null;
2347            }
2348        } else {
2349            visible = false;
2350            for (int i = 0; i < visibilityWindowListeners.length; i++) {
2351                visibilityWindowListeners[i].hide (event);
2352            }
2353        }
2354    } else {
2355        visible = aVisibility != 0;
2356    }
2357    return XPCOM.NS_OK;
2358}
2359
2360int /*long*/ GetTitle (int /*long*/ aTitle) {
2361    return XPCOM.NS_OK;
2362}
2363 
2364int /*long*/ SetTitle (int /*long*/ aTitle) {
2365    if (titleListeners.length == 0) return XPCOM.NS_OK;
2366    TitleEvent event = new TitleEvent (browser);
2367    event.display = browser.getDisplay ();
2368    event.widget = browser;
2369    /*
2370    * To be consistent with other platforms the title event should
2371    * contain the page's url if the page does not contain a <title>
2372    * tag.
2373    */

2374    int length = XPCOM.strlen_PRUnichar (aTitle);
2375    if (length > 0) {
2376        char[] dest = new char[length];
2377        XPCOM.memmove (dest, aTitle, length * 2);
2378        event.title = new String JavaDoc (dest);
2379    } else {
2380        event.title = getUrl ();
2381    }
2382    for (int i = 0; i < titleListeners.length; i++) {
2383        titleListeners[i].changed (event);
2384    }
2385    return XPCOM.NS_OK;
2386}
2387
2388int /*long*/ GetSiteWindow (int /*long*/ aSiteWindow) {
2389    /*
2390    * Note. The handle is expected to be an HWND on Windows and
2391    * a GtkWidget* on GTK. This callback is invoked on Windows
2392    * when the javascript window.print is invoked and the print
2393    * dialog comes up. If no handle is returned, the print dialog
2394    * does not come up on this platform.
2395    */

2396    XPCOM.memmove (aSiteWindow, new int /*long*/[] {embedHandle}, C.PTR_SIZEOF);
2397    return XPCOM.NS_OK;
2398}
2399 
2400/* nsIWebBrowserChromeFocus */
2401
2402int /*long*/ FocusNextElement () {
2403    /*
2404    * Bug in Mozilla embedding API. Mozilla takes back the focus after sending
2405    * this event. This prevents tabbing out of Mozilla. This behaviour can be reproduced
2406    * with the Mozilla application TestGtkEmbed. The workaround is to
2407    * send the traversal notification after this callback returns.
2408    */

2409    browser.getDisplay ().asyncExec (new Runnable JavaDoc () {
2410        public void run () {
2411            browser.traverse (SWT.TRAVERSE_TAB_NEXT);
2412        }
2413    });
2414    return XPCOM.NS_OK;
2415}
2416
2417int /*long*/ FocusPrevElement () {
2418    /*
2419    * Bug in Mozilla embedding API. Mozilla takes back the focus after sending
2420    * this event. This prevents tabbing out of Mozilla. This behaviour can be reproduced
2421    * with the Mozilla application TestGtkEmbed. The workaround is to
2422    * send the traversal notification after this callback returns.
2423    */

2424    browser.getDisplay ().asyncExec (new Runnable JavaDoc () {
2425        public void run () {
2426            browser.traverse (SWT.TRAVERSE_TAB_PREVIOUS);
2427        }
2428    });
2429    return XPCOM.NS_OK;
2430}
2431
2432/* nsIContextMenuListener */
2433
2434int /*long*/ OnShowContextMenu (int /*long*/ aContextFlags, int /*long*/ aEvent, int /*long*/ aNode) {
2435    nsIDOMEvent domEvent = new nsIDOMEvent (aEvent);
2436    int /*long*/[] result = new int /*long*/[1];
2437    int rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result);
2438    if (rc != XPCOM.NS_OK) error (rc);
2439    if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2440
2441    nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]);
2442    int[] aScreenX = new int[1], aScreenY = new int[1];
2443    rc = domMouseEvent.GetScreenX (aScreenX);
2444    if (rc != XPCOM.NS_OK) error (rc);
2445    rc = domMouseEvent.GetScreenY (aScreenY);
2446    if (rc != XPCOM.NS_OK) error (rc);
2447    domMouseEvent.Release ();
2448    
2449    Event event = new Event ();
2450    event.x = aScreenX[0];
2451    event.y = aScreenY[0];
2452    browser.notifyListeners (SWT.MenuDetect, event);
2453    if (!event.doit) return XPCOM.NS_OK;
2454    Menu menu = browser.getMenu ();
2455    if (menu != null && !menu.isDisposed ()) {
2456        if (aScreenX[0] != event.x || aScreenY[0] != event.y) {
2457            menu.setLocation (event.x, event.y);
2458        }
2459        menu.setVisible (true);
2460    }
2461    return XPCOM.NS_OK;
2462}
2463
2464/* nsIURIContentListener */
2465
2466int /*long*/ OnStartURIOpen (int /*long*/ aURI, int /*long*/ retval) {
2467    nsIURI location = new nsIURI (aURI);
2468    int /*long*/ aSpec = XPCOM.nsEmbedCString_new ();
2469    location.GetSpec (aSpec);
2470    int length = XPCOM.nsEmbedCString_Length (aSpec);
2471    int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec);
2472    buffer = XPCOM.nsEmbedCString_get (aSpec);
2473    byte[] dest = new byte[length];
2474    XPCOM.memmove (dest, buffer, length);
2475    XPCOM.nsEmbedCString_delete (aSpec);
2476    String JavaDoc value = new String JavaDoc (dest);
2477    if (locationListeners.length == 0) {
2478        XPCOM.memmove (retval, new int[] {0}, 4); /* PRBool */
2479        return XPCOM.NS_OK;
2480    }
2481    boolean doit = true;
2482    if (request == 0) {
2483        LocationEvent event = new LocationEvent (browser);
2484        event.display = browser.getDisplay();
2485        event.widget = browser;
2486        event.location = value;
2487        /*
2488         * If the URI indicates that the page is being rendered from memory
2489         * (via setText()) then set it to about:blank to be consistent with IE.
2490         */

2491        if (event.location.equals (URI_FROMMEMORY)) event.location = ABOUT_BLANK;
2492        event.doit = doit;
2493        for (int i = 0; i < locationListeners.length; i++) {
2494            locationListeners[i].changing (event);
2495        }
2496        doit = event.doit;
2497    }
2498    XPCOM.memmove (retval, new int[] {doit ? 0 : 1}, 4); /* PRBool */
2499    return XPCOM.NS_OK;
2500}
2501
2502int /*long*/ DoContent (int /*long*/ aContentType, int /*long*/ aIsContentPreferred, int /*long*/ aRequest, int /*long*/ aContentHandler, int /*long*/ retval) {
2503    return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
2504}
2505
2506int /*long*/ IsPreferred (int /*long*/ aContentType, int /*long*/ aDesiredContentType, int /*long*/ retval) {
2507    boolean preferred = false;
2508    int size = XPCOM.strlen (aContentType);
2509    if (size > 0) {
2510        byte[] typeBytes = new byte[size + 1];
2511        XPCOM.memmove (typeBytes, aContentType, size);
2512        String JavaDoc contentType = new String JavaDoc (typeBytes, 0, size);
2513
2514        /* do not attempt to handle known problematic content types */
2515        if (!contentType.equals (XPCOM.CONTENT_MAYBETEXT) && !contentType.equals (XPCOM.CONTENT_MULTIPART)) {
2516            /* determine whether browser can handle the content type */
2517            int /*long*/[] result = new int /*long*/[1];
2518            int rc = XPCOM.NS_GetServiceManager (result);
2519            if (rc != XPCOM.NS_OK) error (rc);
2520            if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2521            nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
2522            result[0] = 0;
2523
2524            /* First try to use the nsIWebNavigationInfo if it's available (>= mozilla 1.8) */
2525            byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WEBNAVIGATIONINFO_CONTRACTID, true);
2526            rc = serviceManager.GetServiceByContractID (aContractID, nsIWebNavigationInfo.NS_IWEBNAVIGATIONINFO_IID, result);
2527            if (rc == 0) {
2528                byte[] bytes = MozillaDelegate.wcsToMbcs (null, contentType, true);
2529                int /*long*/ typePtr = XPCOM.nsEmbedCString_new (bytes, bytes.length);
2530                nsIWebNavigationInfo info = new nsIWebNavigationInfo (result[0]);
2531                result[0] = 0;
2532                int[] isSupportedResult = new int[1]; /* PRUint32 */
2533                rc = info.IsTypeSupported (typePtr, 0, isSupportedResult);
2534                if (rc != XPCOM.NS_OK) error (rc);
2535                info.Release ();
2536                XPCOM.nsEmbedCString_delete (typePtr);
2537                preferred = isSupportedResult[0] != 0;
2538            } else {
2539                /* nsIWebNavigationInfo is not available, so do the type lookup */
2540                result[0] = 0;
2541                rc = serviceManager.GetService (XPCOM.NS_CATEGORYMANAGER_CID, nsICategoryManager.NS_ICATEGORYMANAGER_IID, result);
2542                if (rc != XPCOM.NS_OK) error (rc);
2543                if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2544
2545                nsICategoryManager categoryManager = new nsICategoryManager (result[0]);
2546                result[0] = 0;
2547                byte[] categoryBytes = MozillaDelegate.wcsToMbcs (null, "Gecko-Content-Viewers", true); //$NON-NLS-1$
2548
rc = categoryManager.GetCategoryEntry (categoryBytes, typeBytes, result);
2549                categoryManager.Release ();
2550                /* if no viewer for the content type is registered then rc == XPCOM.NS_ERROR_NOT_AVAILABLE */
2551                preferred = rc == XPCOM.NS_OK;
2552            }
2553            serviceManager.Release ();
2554        }
2555    }
2556
2557    XPCOM.memmove(retval, new int[] {preferred ? 1 : 0}, 4); /* PRBool */
2558    if (preferred) {
2559        XPCOM.memmove (aDesiredContentType, new int /*long*/[] {0}, C.PTR_SIZEOF);
2560    }
2561    return XPCOM.NS_OK;
2562}
2563
2564int /*long*/ CanHandleContent (int /*long*/ aContentType, int /*long*/ aIsContentPreferred, int /*long*/ aDesiredContentType, int /*long*/ retval) {
2565    return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
2566}
2567
2568int /*long*/ GetLoadCookie (int /*long*/ aLoadCookie) {
2569    return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
2570}
2571
2572int /*long*/ SetLoadCookie (int /*long*/ aLoadCookie) {
2573    return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
2574}
2575
2576int /*long*/ GetParentContentListener (int /*long*/ aParentContentListener) {
2577    return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
2578}
2579    
2580int /*long*/ SetParentContentListener (int /*long*/ aParentContentListener) {
2581    return XPCOM.NS_ERROR_NOT_IMPLEMENTED;
2582}
2583
2584/* nsITooltipListener */
2585
2586int /*long*/ OnShowTooltip (int /*long*/ aXCoords, int /*long*/ aYCoords, int /*long*/ aTipText) {
2587    int length = XPCOM.strlen_PRUnichar (aTipText);
2588    char[] dest = new char[length];
2589    XPCOM.memmove (dest, aTipText, length * 2);
2590    String JavaDoc text = new String JavaDoc (dest);
2591    if (tip != null && !tip.isDisposed ()) tip.dispose ();
2592    Display display = browser.getDisplay ();
2593    Shell parent = browser.getShell ();
2594    tip = new Shell (parent, SWT.ON_TOP);
2595    tip.setLayout (new FillLayout());
2596    Label label = new Label (tip, SWT.CENTER);
2597    label.setForeground (display.getSystemColor (SWT.COLOR_INFO_FOREGROUND));
2598    label.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND));
2599    label.setText (text);
2600    /*
2601    * Bug in Mozilla embedded API. Tooltip coordinates are wrong for
2602    * elements inside an inline frame (IFrame tag). The workaround is
2603    * to position the tooltip based on the mouse cursor location.
2604    */

2605    Point point = display.getCursorLocation ();
2606    /* Assuming cursor is 21x21 because this is the size of
2607     * the arrow cursor on Windows
2608     */

2609    point.y += 21;
2610    tip.setLocation (point);
2611    tip.pack ();
2612    tip.setVisible (true);
2613    return XPCOM.NS_OK;
2614}
2615
2616int /*long*/ OnHideTooltip () {
2617    if (tip != null && !tip.isDisposed ()) tip.dispose ();
2618    tip = null;
2619    return XPCOM.NS_OK;
2620}
2621
2622/* nsIDOMEventListener */
2623
2624int /*long*/ HandleEvent (int /*long*/ event) {
2625    nsIDOMEvent domEvent = new nsIDOMEvent (event);
2626
2627    int /*long*/ type = XPCOM.nsEmbedString_new ();
2628    int rc = domEvent.GetType (type);
2629    if (rc != XPCOM.NS_OK) error (rc);
2630    int length = XPCOM.nsEmbedString_Length (type);
2631    int /*long*/ buffer = XPCOM.nsEmbedString_get (type);
2632    char[] chars = new char[length];
2633    XPCOM.memmove (chars, buffer, length * 2);
2634    String JavaDoc typeString = new String JavaDoc (chars);
2635    XPCOM.nsEmbedString_delete (type);
2636
2637    if (XPCOM.DOMEVENT_UNLOAD.equals (typeString)) {
2638        int /*long*/[] result = new int /*long*/[1];
2639        rc = domEvent.GetCurrentTarget (result);
2640        if (rc != XPCOM.NS_OK) error (rc);
2641        if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2642
2643        nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
2644        unhookDOMListeners (target);
2645        target.Release ();
2646        return XPCOM.NS_OK;
2647    }
2648
2649    if (XPCOM.DOMEVENT_FOCUS.equals (typeString)) {
2650        delegate.handleFocus ();
2651        return XPCOM.NS_OK;
2652    }
2653
2654    /* mouse event */
2655
2656    int /*long*/[] result = new int /*long*/[1];
2657    rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result);
2658    if (rc != XPCOM.NS_OK) error (rc);
2659    if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
2660    nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]);
2661    result[0] = 0;
2662
2663    /*
2664     * MouseOver and MouseOut events are fired any time the mouse enters or exits
2665     * any element within the Browser. To ensure that SWT events are only
2666     * fired for mouse movements into or out of the Browser, do not fire an
2667     * event if the element being exited (on MouseOver) or entered (on MouseExit)
2668     * is within the Browser.
2669     */

2670    if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString) || XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) {
2671        rc = domMouseEvent.GetRelatedTarget (result);
2672        if (rc != XPCOM.NS_OK) error (rc);
2673        if (result[0] != 0) {
2674            domMouseEvent.Release ();
2675            return XPCOM.NS_OK;
2676        }
2677    }
2678
2679    int[] aClientX = new int[1], aClientY = new int[1], aDetail = new int[1]; /* PRInt32 */
2680    rc = domMouseEvent.GetClientX (aClientX);
2681    if (rc != XPCOM.NS_OK) error (rc);
2682    rc = domMouseEvent.GetClientY (aClientY);
2683    if (rc != XPCOM.NS_OK) error (rc);
2684    rc = domMouseEvent.GetDetail (aDetail);
2685    if (rc != XPCOM.NS_OK) error (rc);
2686    short[] aButton = new short[1]; /* PRUint16 */
2687    rc = domMouseEvent.GetButton (aButton);
2688    if (rc != XPCOM.NS_OK) error (rc);
2689    boolean[] aAltKey = new boolean[1], aCtrlKey = new boolean[1], aShiftKey = new boolean[1], aMetaKey = new boolean[1];
2690    rc = domMouseEvent.GetAltKey (aAltKey);
2691    if (rc != XPCOM.NS_OK) error (rc);
2692    rc = domMouseEvent.GetCtrlKey (aCtrlKey);
2693    if (rc != XPCOM.NS_OK) error (rc);
2694    rc = domMouseEvent.GetShiftKey (aShiftKey);
2695    if (rc != XPCOM.NS_OK) error (rc);
2696    rc = domMouseEvent.GetMetaKey (aMetaKey);
2697    if (rc != XPCOM.NS_OK) error (rc);
2698    domMouseEvent.Release ();
2699
2700    Event mouseEvent = new Event ();
2701    mouseEvent.widget = browser;
2702    mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0];
2703    mouseEvent.stateMask = (aAltKey[0] ? SWT.ALT : 0) | (aCtrlKey[0] ? SWT.CTRL : 0) | (aShiftKey[0] ? SWT.SHIFT : 0) | (aMetaKey[0] ? SWT.MOD1 : 0);
2704
2705    if (XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) {
2706        mouseEvent.type = SWT.MouseDown;
2707        mouseEvent.button = aButton[0] + 1;
2708        mouseEvent.count = aDetail[0];
2709    } else if (XPCOM.DOMEVENT_MOUSEUP.equals (typeString)) {
2710        mouseEvent.type = SWT.MouseUp;
2711        mouseEvent.button = aButton[0] + 1;
2712        mouseEvent.count = aDetail[0];
2713    } else if (XPCOM.DOMEVENT_MOUSEMOVE.equals (typeString)) {
2714        mouseEvent.type = SWT.MouseMove;
2715    } else if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString)) {
2716        mouseEvent.type = SWT.MouseEnter;
2717    } else if (XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) {
2718        mouseEvent.type = SWT.MouseExit;
2719    }
2720
2721    browser.notifyListeners (mouseEvent.type, mouseEvent);
2722    if (aDetail[0] == 2 && XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) {
2723        mouseEvent = new Event ();
2724        mouseEvent.widget = browser;
2725        mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0];
2726        mouseEvent.stateMask = (aAltKey[0] ? SWT.ALT : 0) | (aCtrlKey[0] ? SWT.CTRL : 0) | (aShiftKey[0] ? SWT.SHIFT : 0) | (aMetaKey[0] ? SWT.MOD1 : 0);
2727        mouseEvent.type = SWT.MouseDoubleClick;
2728        mouseEvent.button = aButton[0] + 1;
2729        mouseEvent.count = aDetail[0];
2730        browser.notifyListeners (mouseEvent.type, mouseEvent);
2731    }
2732    return XPCOM.NS_OK;
2733}
2734}
2735
Popular Tags