Mercurial > projects > dwt-mac
comparison dwt/browser/Mozilla.d @ 0:380af2bdd8e5
Upload of whole dwt tree
author | Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com> |
---|---|
date | Sat, 09 Aug 2008 17:00:02 +0200 |
parents | |
children | 649b8e223d5a |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:380af2bdd8e5 |
---|---|
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 module dwt.browser.Mozilla; | |
12 | |
13 import dwt.dwthelper.utils; | |
14 | |
15 import java.io.UnsupportedEncodingException; | |
16 import java.lang.reflect.Constructor; | |
17 import java.lang.reflect.InvocationTargetException; | |
18 import java.lang.reflect.Method; | |
19 import java.util.Enumeration; | |
20 import java.util.Locale; | |
21 import java.util.Vector; | |
22 | |
23 import dwt.DWT; | |
24 import dwt.DWTError; | |
25 import dwt.graphics.Device; | |
26 import dwt.graphics.Point; | |
27 import dwt.graphics.Rectangle; | |
28 import dwt.internal.C; | |
29 import dwt.internal.Compatibility; | |
30 import dwt.internal.LONG; | |
31 import dwt.internal.Library; | |
32 import dwt.internal.mozilla.GREVersionRange; | |
33 import dwt.internal.mozilla.XPCOM; | |
34 import dwt.internal.mozilla.XPCOMInit; | |
35 import dwt.internal.mozilla.XPCOMObject; | |
36 import dwt.internal.mozilla.nsEmbedString; | |
37 import dwt.internal.mozilla.nsIAppShell; | |
38 import dwt.internal.mozilla.nsIBaseWindow; | |
39 import dwt.internal.mozilla.nsICategoryManager; | |
40 import dwt.internal.mozilla.nsIComponentManager; | |
41 import dwt.internal.mozilla.nsIComponentRegistrar; | |
42 import dwt.internal.mozilla.nsIContextMenuListener; | |
43 import dwt.internal.mozilla.nsICookie; | |
44 import dwt.internal.mozilla.nsICookieManager; | |
45 import dwt.internal.mozilla.nsID; | |
46 import dwt.internal.mozilla.nsIDOMEvent; | |
47 import dwt.internal.mozilla.nsIDOMEventTarget; | |
48 import dwt.internal.mozilla.nsIDOMKeyEvent; | |
49 import dwt.internal.mozilla.nsIDOMMouseEvent; | |
50 import dwt.internal.mozilla.nsIDOMSerializer; | |
51 import dwt.internal.mozilla.nsIDOMSerializer_1_7; | |
52 import dwt.internal.mozilla.nsIDOMWindow; | |
53 import dwt.internal.mozilla.nsIDOMWindowCollection; | |
54 import dwt.internal.mozilla.nsIDirectoryService; | |
55 import dwt.internal.mozilla.nsIDocShell; | |
56 import dwt.internal.mozilla.nsIDocShell_1_8; | |
57 import dwt.internal.mozilla.nsIDocShell_1_9; | |
58 import dwt.internal.mozilla.nsIEmbeddingSiteWindow; | |
59 import dwt.internal.mozilla.nsIFile; | |
60 import dwt.internal.mozilla.nsIIOService; | |
61 import dwt.internal.mozilla.nsIInterfaceRequestor; | |
62 import dwt.internal.mozilla.nsIJSContextStack; | |
63 import dwt.internal.mozilla.nsILocalFile; | |
64 import dwt.internal.mozilla.nsIObserverService; | |
65 import dwt.internal.mozilla.nsIPrefBranch; | |
66 import dwt.internal.mozilla.nsIPrefLocalizedString; | |
67 import dwt.internal.mozilla.nsIPrefService; | |
68 import dwt.internal.mozilla.nsIProperties; | |
69 import dwt.internal.mozilla.nsIServiceManager; | |
70 import dwt.internal.mozilla.nsISimpleEnumerator; | |
71 import dwt.internal.mozilla.nsISupports; | |
72 import dwt.internal.mozilla.nsISupportsWeakReference; | |
73 import dwt.internal.mozilla.nsITooltipListener; | |
74 import dwt.internal.mozilla.nsIURI; | |
75 import dwt.internal.mozilla.nsIURIContentListener; | |
76 import dwt.internal.mozilla.nsIWeakReference; | |
77 import dwt.internal.mozilla.nsIWebBrowser; | |
78 import dwt.internal.mozilla.nsIWebBrowserChrome; | |
79 import dwt.internal.mozilla.nsIWebBrowserChromeFocus; | |
80 import dwt.internal.mozilla.nsIWebBrowserFocus; | |
81 import dwt.internal.mozilla.nsIWebNavigation; | |
82 import dwt.internal.mozilla.nsIWebNavigationInfo; | |
83 import dwt.internal.mozilla.nsIWebProgress; | |
84 import dwt.internal.mozilla.nsIWebProgressListener; | |
85 import dwt.internal.mozilla.nsIWindowWatcher; | |
86 import dwt.layout.FillLayout; | |
87 import dwt.widgets.Composite; | |
88 import dwt.widgets.Display; | |
89 import dwt.widgets.Event; | |
90 import dwt.widgets.Label; | |
91 import dwt.widgets.Listener; | |
92 import dwt.widgets.Menu; | |
93 import dwt.widgets.Shell; | |
94 | |
95 class Mozilla extends WebBrowser { | |
96 int /*long*/ embedHandle; | |
97 nsIWebBrowser webBrowser; | |
98 Object webBrowserObject; | |
99 MozillaDelegate delegate; | |
100 | |
101 /* Interfaces for this Mozilla embedding notification */ | |
102 XPCOMObject supports; | |
103 XPCOMObject weakReference; | |
104 XPCOMObject webProgressListener; | |
105 XPCOMObject webBrowserChrome; | |
106 XPCOMObject webBrowserChromeFocus; | |
107 XPCOMObject embeddingSiteWindow; | |
108 XPCOMObject interfaceRequestor; | |
109 XPCOMObject supportsWeakReference; | |
110 XPCOMObject contextMenuListener; | |
111 XPCOMObject uriContentListener; | |
112 XPCOMObject tooltipListener; | |
113 XPCOMObject domEventListener; | |
114 int chromeFlags = nsIWebBrowserChrome.CHROME_DEFAULT; | |
115 int refCount, lastKeyCode, lastCharCode; | |
116 int /*long*/ request; | |
117 Point location, size; | |
118 bool visible, isChild, ignoreDispose, awaitingNavigate; | |
119 Shell tip = null; | |
120 Listener listener; | |
121 Vector unhookedDOMWindows = new Vector (); | |
122 | |
123 static nsIAppShell AppShell; | |
124 static AppFileLocProvider LocationProvider; | |
125 static WindowCreator2 WindowCreator; | |
126 static int BrowserCount; | |
127 static bool Initialized, IsPre_1_8, PerformedVersionCheck, XPCOMWasGlued, XPCOMInitWasGlued; | |
128 | |
129 /* XULRunner detect constants */ | |
130 static final String GRERANGE_LOWER = "1.8.1.2"; //$NON-NLS-1$ | |
131 static final String GRERANGE_LOWER_FALLBACK = "1.8"; //$NON-NLS-1$ | |
132 static final bool LowerRangeInclusive = true; | |
133 static final String GRERANGE_UPPER = "1.9.*"; //$NON-NLS-1$ | |
134 static final bool UpperRangeInclusive = true; | |
135 | |
136 static final int MAX_PORT = 65535; | |
137 static final String SEPARATOR_OS = System.getProperty ("file.separator"); //$NON-NLS-1$ | |
138 static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$ | |
139 static final String DISPOSE_LISTENER_HOOKED = "dwt.browser.Mozilla.disposeListenerHooked"; //$NON-NLS-1$ | |
140 static final String PREFIX_JAVASCRIPT = "javascript:"; //$NON-NLS-1$ | |
141 static final String PREFERENCE_CHARSET = "intl.charset.default"; //$NON-NLS-1$ | |
142 static final String PREFERENCE_DISABLEOPENDURINGLOAD = "dom.disable_open_during_load"; //$NON-NLS-1$ | |
143 static final String PREFERENCE_DISABLEWINDOWSTATUSCHANGE = "dom.disable_window_status_change"; //$NON-NLS-1$ | |
144 static final String PREFERENCE_LANGUAGES = "intl.accept_languages"; //$NON-NLS-1$ | |
145 static final String PREFERENCE_PROXYHOST_FTP = "network.proxy.ftp"; //$NON-NLS-1$ | |
146 static final String PREFERENCE_PROXYPORT_FTP = "network.proxy.ftp_port"; //$NON-NLS-1$ | |
147 static final String PREFERENCE_PROXYHOST_HTTP = "network.proxy.http"; //$NON-NLS-1$ | |
148 static final String PREFERENCE_PROXYPORT_HTTP = "network.proxy.http_port"; //$NON-NLS-1$ | |
149 static final String PREFERENCE_PROXYHOST_SSL = "network.proxy.ssl"; //$NON-NLS-1$ | |
150 static final String PREFERENCE_PROXYPORT_SSL = "network.proxy.ssl_port"; //$NON-NLS-1$ | |
151 static final String PREFERENCE_PROXYTYPE = "network.proxy.type"; //$NON-NLS-1$ | |
152 static final String PROFILE_AFTER_CHANGE = "profile-after-change"; //$NON-NLS-1$ | |
153 static final String PROFILE_BEFORE_CHANGE = "profile-before-change"; //$NON-NLS-1$ | |
154 static final String PROFILE_DIR = SEPARATOR_OS + "eclipse" + SEPARATOR_OS; //$NON-NLS-1$ | |
155 static final String PROFILE_DO_CHANGE = "profile-do-change"; //$NON-NLS-1$ | |
156 static final String PROPERTY_PROXYPORT = "network.proxy_port"; //$NON-NLS-1$ | |
157 static final String PROPERTY_PROXYHOST = "network.proxy_host"; //$NON-NLS-1$ | |
158 static final String SEPARATOR_LOCALE = "-"; //$NON-NLS-1$ | |
159 static final String SHUTDOWN_PERSIST = "shutdown-persist"; //$NON-NLS-1$ | |
160 static final String STARTUP = "startup"; //$NON-NLS-1$ | |
161 static final String TOKENIZER_LOCALE = ","; //$NON-NLS-1$ | |
162 static final String URI_FROMMEMORY = "file:///"; //$NON-NLS-1$ | |
163 static final String XULRUNNER_PATH = "dwt.browser.XULRunnerPath"; //$NON-NLS-1$ | |
164 | |
165 // TEMPORARY CODE | |
166 static final String GRE_INITIALIZED = "dwt.browser.XULRunnerInitialized"; //$NON-NLS-1$ | |
167 | |
168 static { | |
169 MozillaClearSessions = new Runnable () { | |
170 public void run () { | |
171 if (!Initialized) return; | |
172 int /*long*/[] result = new int /*long*/[1]; | |
173 int rc = XPCOM.NS_GetServiceManager (result); | |
174 if (rc !is XPCOM.NS_OK) error (rc); | |
175 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
176 nsIServiceManager serviceManager = new nsIServiceManager (result[0]); | |
177 result[0] = 0; | |
178 byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIEMANAGER_CONTRACTID, true); | |
179 rc = serviceManager.GetServiceByContractID (aContractID, nsICookieManager.NS_ICOOKIEMANAGER_IID, result); | |
180 if (rc !is XPCOM.NS_OK) error (rc); | |
181 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
182 serviceManager.Release (); | |
183 | |
184 nsICookieManager manager = new nsICookieManager (result[0]); | |
185 result[0] = 0; | |
186 rc = manager.GetEnumerator (result); | |
187 if (rc !is XPCOM.NS_OK) error (rc); | |
188 manager.Release (); | |
189 | |
190 nsISimpleEnumerator enumerator = new nsISimpleEnumerator (result[0]); | |
191 int[] moreElements = new int[1]; /* PRBool */ | |
192 rc = enumerator.HasMoreElements (moreElements); | |
193 if (rc !is XPCOM.NS_OK) error (rc); | |
194 while (moreElements[0] !is 0) { | |
195 result[0] = 0; | |
196 rc = enumerator.GetNext (result); | |
197 if (rc !is XPCOM.NS_OK) error (rc); | |
198 nsICookie cookie = new nsICookie (result[0]); | |
199 long[] expires = new long[1]; | |
200 rc = cookie.GetExpires (expires); | |
201 if (expires[0] is 0) { | |
202 /* indicates a session cookie */ | |
203 int /*long*/ domain = XPCOM.nsEmbedCString_new (); | |
204 int /*long*/ name = XPCOM.nsEmbedCString_new (); | |
205 int /*long*/ path = XPCOM.nsEmbedCString_new (); | |
206 cookie.GetHost (domain); | |
207 cookie.GetName (name); | |
208 cookie.GetPath (path); | |
209 rc = manager.Remove (domain, name, path, 0); | |
210 XPCOM.nsEmbedCString_delete (domain); | |
211 XPCOM.nsEmbedCString_delete (name); | |
212 XPCOM.nsEmbedCString_delete (path); | |
213 if (rc !is XPCOM.NS_OK) error (rc); | |
214 } | |
215 cookie.Release (); | |
216 rc = enumerator.HasMoreElements (moreElements); | |
217 if (rc !is XPCOM.NS_OK) error (rc); | |
218 } | |
219 enumerator.Release (); | |
220 } | |
221 }; | |
222 } | |
223 | |
224 public void create (Composite parent, int style) { | |
225 delegate = new MozillaDelegate (browser); | |
226 Display display = parent.getDisplay (); | |
227 | |
228 int /*long*/[] result = new int /*long*/[1]; | |
229 if (!Initialized) { | |
230 bool initLoaded = false; | |
231 bool IsXULRunner = false; | |
232 | |
233 String greInitialized = System.getProperty (GRE_INITIALIZED); | |
234 if ("true".equals (greInitialized)) { //$NON-NLS-1$ | |
235 /* | |
236 * Another browser has already initialized xulrunner in this process, | |
237 * so just bind to it instead of trying to initialize a new one. | |
238 */ | |
239 Initialized = true; | |
240 } | |
241 | |
242 String mozillaPath = System.getProperty (XULRUNNER_PATH); | |
243 /* | |
244 * Browser clients that ship XULRunner in a plug-in must have an opportunity | |
245 * to set the dwt.browser.XULRunnerPath system property to point | |
246 * at their XULRunner before the first Mozilla-based Browser is created. To | |
247 * facilitate this, reflection is used to reference non-existent class | |
248 * dwt.browser.XULRunnerInitializer the first time a Mozilla- | |
249 * based Browser is created. A client wishing to use this hook can do so | |
250 * by creating a fragment of dwt that implements this class and | |
251 * sets the system property in its static initializer. | |
252 */ | |
253 if (mozillaPath is null) { | |
254 try { | |
255 Class.forName ("dwt.browser.XULRunnerInitializer"); //$NON-NLS-1$ | |
256 mozillaPath = System.getProperty (XULRUNNER_PATH); | |
257 } catch (ClassNotFoundException e) { | |
258 /* no fragment is providing this class, which is the typical case */ | |
259 } | |
260 } | |
261 | |
262 if (mozillaPath is null) { | |
263 try { | |
264 String libName = delegate.getSWTInitLibraryName (); | |
265 Library.loadLibrary (libName); | |
266 initLoaded = true; | |
267 } catch (UnsatisfiedLinkError e) { | |
268 /* | |
269 * If this library failed to load then do not attempt to detect a | |
270 * xulrunner to use. The Browser may still be usable if MOZILLA_FIVE_HOME | |
271 * points at a GRE. | |
272 */ | |
273 } | |
274 } else { | |
275 mozillaPath += SEPARATOR_OS + delegate.getLibraryName (); | |
276 IsXULRunner = true; | |
277 } | |
278 | |
279 if (initLoaded) { | |
280 /* attempt to discover a XULRunner to use as the GRE */ | |
281 GREVersionRange range = new GREVersionRange (); | |
282 byte[] bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER, true); | |
283 int /*long*/ lower = C.malloc (bytes.length); | |
284 C.memmove (lower, bytes, bytes.length); | |
285 range.lower = lower; | |
286 range.lowerInclusive = LowerRangeInclusive; | |
287 | |
288 bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_UPPER, true); | |
289 int /*long*/ upper = C.malloc (bytes.length); | |
290 C.memmove (upper, bytes, bytes.length); | |
291 range.upper = upper; | |
292 range.upperInclusive = UpperRangeInclusive; | |
293 | |
294 int length = XPCOMInit.PATH_MAX; | |
295 int /*long*/ greBuffer = C.malloc (length); | |
296 int /*long*/ propertiesPtr = C.malloc (2 * C.PTR_SIZEOF); | |
297 int rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length); | |
298 | |
299 /* | |
300 * A XULRunner was not found that supports wrapping of XPCOM handles as JavaXPCOM objects. | |
301 * Drop the lower version bound and try to detect an earlier XULRunner installation. | |
302 */ | |
303 if (rc !is XPCOM.NS_OK) { | |
304 C.free (lower); | |
305 bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER_FALLBACK, true); | |
306 lower = C.malloc (bytes.length); | |
307 C.memmove (lower, bytes, bytes.length); | |
308 range.lower = lower; | |
309 rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length); | |
310 } | |
311 | |
312 C.free (lower); | |
313 C.free (upper); | |
314 C.free (propertiesPtr); | |
315 if (rc is XPCOM.NS_OK) { | |
316 /* indicates that a XULRunner was found */ | |
317 length = C.strlen (greBuffer); | |
318 bytes = new byte[length]; | |
319 C.memmove (bytes, greBuffer, length); | |
320 mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, bytes)); | |
321 IsXULRunner = mozillaPath.length () > 0; | |
322 | |
323 /* | |
324 * Test whether the detected XULRunner can be used as the GRE before loading swt's | |
325 * XULRunner library. If it cannot be used then fall back to attempting to use | |
326 * the GRE pointed to by MOZILLA_FIVE_HOME. | |
327 * | |
328 * One case where this will fail is attempting to use a 64-bit xulrunner while swt | |
329 * is running in 32-bit mode, or vice versa. | |
330 */ | |
331 if (IsXULRunner) { | |
332 byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true); | |
333 rc = XPCOMInit.XPCOMGlueStartup (path); | |
334 if (rc !is XPCOM.NS_OK) { | |
335 IsXULRunner = false; /* failed */ | |
336 mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS)); | |
337 if (Device.DEBUG) System.out.println ("cannot use detected XULRunner: " + mozillaPath); //$NON-NLS-1$ | |
338 } else { | |
339 XPCOMInitWasGlued = true; | |
340 } | |
341 } | |
342 } | |
343 C.free (greBuffer); | |
344 } | |
345 | |
346 if (IsXULRunner) { | |
347 if (Device.DEBUG) System.out.println ("XULRunner path: " + mozillaPath); //$NON-NLS-1$ | |
348 try { | |
349 Library.loadLibrary ("swt-xulrunner"); //$NON-NLS-1$ | |
350 } catch (UnsatisfiedLinkError e) { | |
351 DWT.error (DWT.ERROR_NO_HANDLES, e); | |
352 } | |
353 byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true); | |
354 int rc = XPCOM.XPCOMGlueStartup (path); | |
355 if (rc !is XPCOM.NS_OK) { | |
356 browser.dispose (); | |
357 error (rc); | |
358 } | |
359 XPCOMWasGlued = true; | |
360 | |
361 /* | |
362 * Remove the trailing xpcom lib name from mozillaPath because the | |
363 * Mozilla.initialize and NS_InitXPCOM2 invocations require a directory name only. | |
364 */ | |
365 mozillaPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS)); | |
366 } else { | |
367 if ((style & DWT.MOZILLA) !is 0) { | |
368 browser.dispose (); | |
369 String errorString = (mozillaPath !is null && mozillaPath.length () > 0) ? | |
370 " [Failed to use detected XULRunner: " + mozillaPath + "]" : | |
371 " [Could not detect registered XULRunner to use]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
372 DWT.error (DWT.ERROR_NO_HANDLES, null, errorString); | |
373 } | |
374 | |
375 /* attempt to use the GRE pointed at by MOZILLA_FIVE_HOME */ | |
376 int /*long*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, XPCOM.MOZILLA_FIVE_HOME, true)); | |
377 if (ptr !is 0) { | |
378 int length = C.strlen (ptr); | |
379 byte[] buffer = new byte[length]; | |
380 C.memmove (buffer, ptr, length); | |
381 mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, buffer)); | |
382 } else { | |
383 browser.dispose (); | |
384 DWT.error (DWT.ERROR_NO_HANDLES, null, " [Unknown Mozilla path (MOZILLA_FIVE_HOME not set)]"); //$NON-NLS-1$ | |
385 } | |
386 if (Device.DEBUG) System.out.println ("Mozilla path: " + mozillaPath); //$NON-NLS-1$ | |
387 | |
388 /* | |
389 * Note. Embedding a Mozilla GTK1.2 causes a crash. The workaround | |
390 * is to check the version of GTK used by Mozilla by looking for | |
391 * the libwidget_gtk.so library used by Mozilla GTK1.2. Mozilla GTK2 | |
392 * uses the libwidget_gtk2.so library. | |
393 */ | |
394 if (Compatibility.fileExists (mozillaPath, "components/libwidget_gtk.so")) { //$NON-NLS-1$ | |
395 browser.dispose (); | |
396 DWT.error (DWT.ERROR_NO_HANDLES, null, " [Mozilla GTK2 required (GTK1.2 detected)]"); //$NON-NLS-1$ | |
397 } | |
398 | |
399 try { | |
400 Library.loadLibrary ("swt-mozilla"); //$NON-NLS-1$ | |
401 } catch (UnsatisfiedLinkError e) { | |
402 try { | |
403 /* | |
404 * The initial loadLibrary attempt may have failed as a result of the user's | |
405 * system not having libstdc++.so.6 installed, so try to load the alternate | |
406 * swt mozilla library that depends on libswtc++.so.5 instead. | |
407 */ | |
408 Library.loadLibrary ("swt-mozilla-gcc3"); //$NON-NLS-1$ | |
409 } catch (UnsatisfiedLinkError ex) { | |
410 browser.dispose (); | |
411 /* | |
412 * Print the error from the first failed attempt since at this point it's | |
413 * known that the failure was not due to the libstdc++.so.6 dependency. | |
414 */ | |
415 DWT.error (DWT.ERROR_NO_HANDLES, e, " [MOZILLA_FIVE_HOME='" + mozillaPath + "']"); //$NON-NLS-1$ //$NON-NLS-2$ | |
416 } | |
417 } | |
418 } | |
419 | |
420 if (!Initialized) { | |
421 int /*long*/[] retVal = new int /*long*/[1]; | |
422 nsEmbedString pathString = new nsEmbedString (mozillaPath); | |
423 int rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, retVal); | |
424 pathString.dispose (); | |
425 if (rc !is XPCOM.NS_OK) { | |
426 browser.dispose (); | |
427 error (rc); | |
428 } | |
429 if (retVal[0] is 0) { | |
430 browser.dispose (); | |
431 error (XPCOM.NS_ERROR_NULL_POINTER); | |
432 } | |
433 | |
434 LocationProvider = new AppFileLocProvider (mozillaPath); | |
435 LocationProvider.AddRef (); | |
436 | |
437 nsIFile localFile = new nsILocalFile (retVal[0]); | |
438 rc = XPCOM.NS_InitXPCOM2 (0, localFile.getAddress(), LocationProvider.getAddress ()); | |
439 localFile.Release (); | |
440 if (rc !is XPCOM.NS_OK) { | |
441 browser.dispose (); | |
442 DWT.error (DWT.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$ | |
443 } | |
444 System.setProperty (GRE_INITIALIZED, "true"); //$NON-NLS-1$ | |
445 if (IsXULRunner) { | |
446 System.setProperty (XULRUNNER_PATH, mozillaPath); | |
447 } | |
448 } | |
449 | |
450 /* If JavaXPCOM is detected then attempt to initialize it with the XULRunner being used */ | |
451 if (IsXULRunner) { | |
452 try { | |
453 Class clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$ | |
454 Method method = clazz.getMethod ("getInstance", new Class[0]); //$NON-NLS-1$ | |
455 Object mozilla = method.invoke (null, new Object[0]); | |
456 method = clazz.getMethod ("getComponentManager", new Class[0]); //$NON-NLS-1$ | |
457 try { | |
458 method.invoke (mozilla, new Object[0]); | |
459 } catch (InvocationTargetException e) { | |
460 /* indicates that JavaXPCOM has not been initialized yet */ | |
461 Class fileClass = Class.forName ("java.io.File"); //$NON-NLS-1$ | |
462 method = clazz.getMethod ("initialize", new Class[] {fileClass}); //$NON-NLS-1$ | |
463 Constructor constructor = fileClass.getDeclaredConstructor (new Class[] {String.class}); | |
464 Object argument = constructor.newInstance (new Object[] {mozillaPath}); | |
465 method.invoke (mozilla, new Object[] {argument}); | |
466 } | |
467 } catch (ClassNotFoundException e) { | |
468 /* JavaXPCOM is not on the classpath */ | |
469 } catch (NoSuchMethodException e) { | |
470 /* the JavaXPCOM on the classpath does not implement initialize() */ | |
471 } catch (IllegalArgumentException e) { | |
472 } catch (IllegalAccessException e) { | |
473 } catch (InvocationTargetException e) { | |
474 } catch (InstantiationException e) { | |
475 } | |
476 } | |
477 | |
478 int rc = XPCOM.NS_GetComponentManager (result); | |
479 if (rc !is XPCOM.NS_OK) { | |
480 browser.dispose (); | |
481 error (rc); | |
482 } | |
483 if (result[0] is 0) { | |
484 browser.dispose (); | |
485 error (XPCOM.NS_NOINTERFACE); | |
486 } | |
487 | |
488 nsIComponentManager componentManager = new nsIComponentManager (result[0]); | |
489 result[0] = 0; | |
490 if (delegate.needsSpinup ()) { | |
491 /* nsIAppShell is discontinued as of xulrunner 1.9, so do not fail if it is not found */ | |
492 rc = componentManager.CreateInstance (XPCOM.NS_APPSHELL_CID, 0, nsIAppShell.NS_IAPPSHELL_IID, result); | |
493 if (rc !is XPCOM.NS_ERROR_NO_INTERFACE) { | |
494 if (rc !is XPCOM.NS_OK) { | |
495 browser.dispose (); | |
496 error (rc); | |
497 } | |
498 if (result[0] is 0) { | |
499 browser.dispose (); | |
500 error (XPCOM.NS_NOINTERFACE); | |
501 } | |
502 | |
503 AppShell = new nsIAppShell (result[0]); | |
504 rc = AppShell.Create (0, null); | |
505 if (rc !is XPCOM.NS_OK) { | |
506 browser.dispose (); | |
507 error (rc); | |
508 } | |
509 rc = AppShell.Spinup (); | |
510 if (rc !is XPCOM.NS_OK) { | |
511 browser.dispose (); | |
512 error (rc); | |
513 } | |
514 } | |
515 result[0] = 0; | |
516 } | |
517 | |
518 WindowCreator = new WindowCreator2 (); | |
519 WindowCreator.AddRef (); | |
520 | |
521 rc = XPCOM.NS_GetServiceManager (result); | |
522 if (rc !is XPCOM.NS_OK) { | |
523 browser.dispose (); | |
524 error (rc); | |
525 } | |
526 if (result[0] is 0) { | |
527 browser.dispose (); | |
528 error (XPCOM.NS_NOINTERFACE); | |
529 } | |
530 | |
531 nsIServiceManager serviceManager = new nsIServiceManager (result[0]); | |
532 result[0] = 0; | |
533 byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true); | |
534 rc = serviceManager.GetServiceByContractID (aContractID, nsIWindowWatcher.NS_IWINDOWWATCHER_IID, result); | |
535 if (rc !is XPCOM.NS_OK) { | |
536 browser.dispose (); | |
537 error (rc); | |
538 } | |
539 if (result[0] is 0) { | |
540 browser.dispose (); | |
541 error (XPCOM.NS_NOINTERFACE); | |
542 } | |
543 | |
544 nsIWindowWatcher windowWatcher = new nsIWindowWatcher (result[0]); | |
545 result[0] = 0; | |
546 rc = windowWatcher.SetWindowCreator (WindowCreator.getAddress()); | |
547 if (rc !is XPCOM.NS_OK) { | |
548 browser.dispose (); | |
549 error (rc); | |
550 } | |
551 windowWatcher.Release (); | |
552 | |
553 /* compute the profile directory and set it on the AppFileLocProvider */ | |
554 if (LocationProvider !is null) { | |
555 byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DIRECTORYSERVICE_CONTRACTID, true); | |
556 rc = serviceManager.GetServiceByContractID (buffer, nsIDirectoryService.NS_IDIRECTORYSERVICE_IID, result); | |
557 if (rc !is XPCOM.NS_OK) { | |
558 browser.dispose (); | |
559 error (rc); | |
560 } | |
561 if (result[0] is 0) { | |
562 browser.dispose (); | |
563 error (XPCOM.NS_NOINTERFACE); | |
564 } | |
565 | |
566 nsIDirectoryService directoryService = new nsIDirectoryService (result[0]); | |
567 result[0] = 0; | |
568 rc = directoryService.QueryInterface (nsIProperties.NS_IPROPERTIES_IID, result); | |
569 if (rc !is XPCOM.NS_OK) { | |
570 browser.dispose (); | |
571 error (rc); | |
572 } | |
573 if (result[0] is 0) { | |
574 browser.dispose (); | |
575 error (XPCOM.NS_NOINTERFACE); | |
576 } | |
577 directoryService.Release (); | |
578 | |
579 nsIProperties properties = new nsIProperties (result[0]); | |
580 result[0] = 0; | |
581 buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_APP_APPLICATION_REGISTRY_DIR, true); | |
582 rc = properties.Get (buffer, nsIFile.NS_IFILE_IID, result); | |
583 if (rc !is XPCOM.NS_OK) { | |
584 browser.dispose (); | |
585 error (rc); | |
586 } | |
587 if (result[0] is 0) { | |
588 browser.dispose (); | |
589 error (XPCOM.NS_NOINTERFACE); | |
590 } | |
591 properties.Release (); | |
592 | |
593 nsIFile profileDir = new nsIFile (result[0]); | |
594 result[0] = 0; | |
595 int /*long*/ path = XPCOM.nsEmbedCString_new (); | |
596 rc = profileDir.GetNativePath (path); | |
597 if (rc !is XPCOM.NS_OK) { | |
598 browser.dispose (); | |
599 error (rc); | |
600 } | |
601 int length = XPCOM.nsEmbedCString_Length (path); | |
602 int /*long*/ ptr = XPCOM.nsEmbedCString_get (path); | |
603 buffer = new byte [length]; | |
604 XPCOM.memmove (buffer, ptr, length); | |
605 String profilePath = new String (MozillaDelegate.mbcsToWcs (null, buffer)) + PROFILE_DIR; | |
606 LocationProvider.setProfilePath (profilePath); | |
607 LocationProvider.isXULRunner = IsXULRunner; | |
608 XPCOM.nsEmbedCString_delete (path); | |
609 profileDir.Release (); | |
610 | |
611 /* notify observers of a new profile directory being used */ | |
612 buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true); | |
613 rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result); | |
614 if (rc !is XPCOM.NS_OK) { | |
615 browser.dispose (); | |
616 error (rc); | |
617 } | |
618 if (result[0] is 0) { | |
619 browser.dispose (); | |
620 error (XPCOM.NS_NOINTERFACE); | |
621 } | |
622 | |
623 nsIObserverService observerService = new nsIObserverService (result[0]); | |
624 result[0] = 0; | |
625 buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_DO_CHANGE, true); | |
626 length = STARTUP.length (); | |
627 char[] chars = new char [length + 1]; | |
628 STARTUP.getChars (0, length, chars, 0); | |
629 rc = observerService.NotifyObservers (0, buffer, chars); | |
630 if (rc !is XPCOM.NS_OK) { | |
631 browser.dispose (); | |
632 error (rc); | |
633 } | |
634 buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_AFTER_CHANGE, true); | |
635 rc = observerService.NotifyObservers (0, buffer, chars); | |
636 if (rc !is XPCOM.NS_OK) { | |
637 browser.dispose (); | |
638 error (rc); | |
639 } | |
640 observerService.Release (); | |
641 } | |
642 | |
643 /* | |
644 * As a result of using a common profile the user cannot change their locale | |
645 * and charset. The fix for this is to set mozilla's locale and charset | |
646 * preference values according to the user's current locale and charset. | |
647 */ | |
648 aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true); | |
649 rc = serviceManager.GetServiceByContractID (aContractID, nsIPrefService.NS_IPREFSERVICE_IID, result); | |
650 serviceManager.Release (); | |
651 if (rc !is XPCOM.NS_OK) { | |
652 browser.dispose (); | |
653 error (rc); | |
654 } | |
655 if (result[0] is 0) { | |
656 browser.dispose (); | |
657 error (XPCOM.NS_NOINTERFACE); | |
658 } | |
659 | |
660 nsIPrefService prefService = new nsIPrefService (result[0]); | |
661 result[0] = 0; | |
662 byte[] buffer = new byte[1]; | |
663 rc = prefService.GetBranch (buffer, result); /* empty buffer denotes root preference level */ | |
664 prefService.Release (); | |
665 if (rc !is XPCOM.NS_OK) { | |
666 browser.dispose (); | |
667 error (rc); | |
668 } | |
669 if (result[0] is 0) { | |
670 browser.dispose (); | |
671 error (XPCOM.NS_NOINTERFACE); | |
672 } | |
673 | |
674 nsIPrefBranch prefBranch = new nsIPrefBranch (result[0]); | |
675 result[0] = 0; | |
676 | |
677 /* get Mozilla's current locale preference value */ | |
678 String prefLocales = null; | |
679 nsIPrefLocalizedString localizedString = null; | |
680 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_LANGUAGES, true); | |
681 rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); | |
682 /* | |
683 * Feature of Debian. For some reason attempting to query for the current locale | |
684 * preference fails on Debian. The workaround for this is to assume a value of | |
685 * "en-us,en" since this is typically the default value when mozilla is used without | |
686 * a profile. | |
687 */ | |
688 if (rc !is XPCOM.NS_OK) { | |
689 prefLocales = "en-us,en" + TOKENIZER_LOCALE; //$NON-NLS-1$ | |
690 } else { | |
691 if (result[0] is 0) { | |
692 browser.dispose (); | |
693 error (XPCOM.NS_NOINTERFACE); | |
694 } | |
695 localizedString = new nsIPrefLocalizedString (result[0]); | |
696 result[0] = 0; | |
697 rc = localizedString.ToString (result); | |
698 if (rc !is XPCOM.NS_OK) { | |
699 browser.dispose (); | |
700 error (rc); | |
701 } | |
702 if (result[0] is 0) { | |
703 browser.dispose (); | |
704 error (XPCOM.NS_NOINTERFACE); | |
705 } | |
706 int length = XPCOM.strlen_PRUnichar (result[0]); | |
707 char[] dest = new char[length]; | |
708 XPCOM.memmove (dest, result[0], length * 2); | |
709 prefLocales = new String (dest) + TOKENIZER_LOCALE; | |
710 } | |
711 result[0] = 0; | |
712 | |
713 /* | |
714 * construct the new locale preference value by prepending the | |
715 * user's current locale and language to the original value | |
716 */ | |
717 Locale locale = Locale.getDefault (); | |
718 String language = locale.getLanguage (); | |
719 String country = locale.getCountry (); | |
720 StringBuffer stringBuffer = new StringBuffer (language); | |
721 stringBuffer.append (SEPARATOR_LOCALE); | |
722 stringBuffer.append (country.toLowerCase ()); | |
723 stringBuffer.append (TOKENIZER_LOCALE); | |
724 stringBuffer.append (language); | |
725 stringBuffer.append (TOKENIZER_LOCALE); | |
726 String newLocales = stringBuffer.toString (); | |
727 | |
728 int start, end = -1; | |
729 do { | |
730 start = end + 1; | |
731 end = prefLocales.indexOf (TOKENIZER_LOCALE, start); | |
732 String token; | |
733 if (end is -1) { | |
734 token = prefLocales.substring (start); | |
735 } else { | |
736 token = prefLocales.substring (start, end); | |
737 } | |
738 if (token.length () > 0) { | |
739 token = (token + TOKENIZER_LOCALE).trim (); | |
740 /* ensure that duplicate locale values are not added */ | |
741 if (newLocales.indexOf (token) is -1) { | |
742 stringBuffer.append (token); | |
743 } | |
744 } | |
745 } while (end !is -1); | |
746 newLocales = stringBuffer.toString (); | |
747 if (!newLocales.equals (prefLocales)) { | |
748 /* write the new locale value */ | |
749 newLocales = newLocales.substring (0, newLocales.length () - TOKENIZER_LOCALE.length ()); /* remove trailing tokenizer */ | |
750 int length = newLocales.length (); | |
751 char[] charBuffer = new char[length + 1]; | |
752 newLocales.getChars (0, length, charBuffer, 0); | |
753 if (localizedString is null) { | |
754 byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); | |
755 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); | |
756 if (rc !is XPCOM.NS_OK) { | |
757 browser.dispose (); | |
758 error (rc); | |
759 } | |
760 if (result[0] is 0) { | |
761 browser.dispose (); | |
762 error (XPCOM.NS_NOINTERFACE); | |
763 } | |
764 localizedString = new nsIPrefLocalizedString (result[0]); | |
765 result[0] = 0; | |
766 } | |
767 localizedString.SetDataWithLength (length, charBuffer); | |
768 rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress()); | |
769 } | |
770 if (localizedString !is null) { | |
771 localizedString.Release (); | |
772 localizedString = null; | |
773 } | |
774 | |
775 /* get Mozilla's current charset preference value */ | |
776 String prefCharset = null; | |
777 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_CHARSET, true); | |
778 rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); | |
779 /* | |
780 * Feature of Debian. For some reason attempting to query for the current charset | |
781 * preference fails on Debian. The workaround for this is to assume a value of | |
782 * "ISO-8859-1" since this is typically the default value when mozilla is used | |
783 * without a profile. | |
784 */ | |
785 if (rc !is XPCOM.NS_OK) { | |
786 prefCharset = "ISO-8859-1"; //$NON_NLS-1$ | |
787 } else { | |
788 if (result[0] is 0) { | |
789 browser.dispose (); | |
790 error (XPCOM.NS_NOINTERFACE); | |
791 } | |
792 localizedString = new nsIPrefLocalizedString (result[0]); | |
793 result[0] = 0; | |
794 rc = localizedString.ToString (result); | |
795 if (rc !is XPCOM.NS_OK) { | |
796 browser.dispose (); | |
797 error (rc); | |
798 } | |
799 if (result[0] is 0) { | |
800 browser.dispose (); | |
801 error (XPCOM.NS_NOINTERFACE); | |
802 } | |
803 int length = XPCOM.strlen_PRUnichar (result[0]); | |
804 char[] dest = new char[length]; | |
805 XPCOM.memmove (dest, result[0], length * 2); | |
806 prefCharset = new String (dest); | |
807 } | |
808 result[0] = 0; | |
809 | |
810 String newCharset = System.getProperty ("file.encoding"); // $NON-NLS-1$ | |
811 if (!newCharset.equals (prefCharset)) { | |
812 /* write the new charset value */ | |
813 int length = newCharset.length (); | |
814 char[] charBuffer = new char[length + 1]; | |
815 newCharset.getChars (0, length, charBuffer, 0); | |
816 if (localizedString is null) { | |
817 byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); | |
818 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); | |
819 if (rc !is XPCOM.NS_OK) { | |
820 browser.dispose (); | |
821 error (rc); | |
822 } | |
823 if (result[0] is 0) { | |
824 browser.dispose (); | |
825 error (XPCOM.NS_NOINTERFACE); | |
826 } | |
827 localizedString = new nsIPrefLocalizedString (result[0]); | |
828 result[0] = 0; | |
829 } | |
830 localizedString.SetDataWithLength (length, charBuffer); | |
831 rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); | |
832 } | |
833 if (localizedString !is null) localizedString.Release (); | |
834 | |
835 /* | |
836 * Check for proxy values set as documented java properties and update mozilla's | |
837 * preferences with these values if needed. | |
838 */ | |
839 String proxyHost = System.getProperty (PROPERTY_PROXYHOST); | |
840 String proxyPortString = System.getProperty (PROPERTY_PROXYPORT); | |
841 | |
842 int port = -1; | |
843 if (proxyPortString !is null) { | |
844 try { | |
845 int value = Integer.valueOf (proxyPortString).intValue (); | |
846 if (0 <= value && value <= MAX_PORT) port = value; | |
847 } catch (NumberFormatException e) { | |
848 /* do nothing, java property has non-integer value */ | |
849 } | |
850 } | |
851 | |
852 if (proxyHost !is null) { | |
853 byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); | |
854 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); | |
855 if (rc !is XPCOM.NS_OK) error (rc); | |
856 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
857 | |
858 localizedString = new nsIPrefLocalizedString (result[0]); | |
859 result[0] = 0; | |
860 int length = proxyHost.length (); | |
861 char[] charBuffer = new char[length + 1]; | |
862 proxyHost.getChars (0, length, charBuffer, 0); | |
863 rc = localizedString.SetDataWithLength (length, charBuffer); | |
864 if (rc !is XPCOM.NS_OK) error (rc); | |
865 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_FTP, true); | |
866 rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); | |
867 if (rc !is XPCOM.NS_OK) error (rc); | |
868 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_HTTP, true); | |
869 rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); | |
870 if (rc !is XPCOM.NS_OK) error (rc); | |
871 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_SSL, true); | |
872 rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); | |
873 if (rc !is XPCOM.NS_OK) error (rc); | |
874 localizedString.Release (); | |
875 } | |
876 | |
877 if (port !is -1) { | |
878 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_FTP, true); | |
879 rc = prefBranch.SetIntPref (buffer, port); | |
880 if (rc !is XPCOM.NS_OK) error (rc); | |
881 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_HTTP, true); | |
882 rc = prefBranch.SetIntPref (buffer, port); | |
883 if (rc !is XPCOM.NS_OK) error (rc); | |
884 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_SSL, true); | |
885 rc = prefBranch.SetIntPref (buffer, port); | |
886 if (rc !is XPCOM.NS_OK) error (rc); | |
887 } | |
888 | |
889 if (proxyHost !is null || port !is -1) { | |
890 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYTYPE, true); | |
891 rc = prefBranch.SetIntPref (buffer, 1); | |
892 if (rc !is XPCOM.NS_OK) error (rc); | |
893 } | |
894 | |
895 /* | |
896 * Ensure that windows that are shown during page loads are not blocked. Firefox may | |
897 * try to block these by default since such windows are often unwelcome, but this | |
898 * assumption should not be made in the Browser's context. Since the Browser client | |
899 * is responsible for creating the new Browser and Shell in an OpenWindowListener, | |
900 * they should decide whether the new window is unwelcome or not and act accordingly. | |
901 */ | |
902 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEOPENDURINGLOAD, true); | |
903 rc = prefBranch.SetBoolPref (buffer, 0); | |
904 if (rc !is XPCOM.NS_OK) { | |
905 browser.dispose (); | |
906 error (rc); | |
907 } | |
908 | |
909 /* Ensure that the status text can be set through means like javascript */ | |
910 buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEWINDOWSTATUSCHANGE, true); | |
911 rc = prefBranch.SetBoolPref (buffer, 0); | |
912 if (rc !is XPCOM.NS_OK) { | |
913 browser.dispose (); | |
914 error (rc); | |
915 } | |
916 | |
917 prefBranch.Release (); | |
918 | |
919 PromptService2Factory factory = new PromptService2Factory (); | |
920 factory.AddRef (); | |
921 | |
922 rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result); | |
923 if (rc !is XPCOM.NS_OK) { | |
924 browser.dispose (); | |
925 error (rc); | |
926 } | |
927 if (result[0] is 0) { | |
928 browser.dispose (); | |
929 error (XPCOM.NS_NOINTERFACE); | |
930 } | |
931 | |
932 nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]); | |
933 result[0] = 0; | |
934 aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PROMPTSERVICE_CONTRACTID, true); | |
935 byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "Prompt Service", true); //$NON-NLS-1$ | |
936 rc = componentRegistrar.RegisterFactory (XPCOM.NS_PROMPTSERVICE_CID, aClassName, aContractID, factory.getAddress ()); | |
937 if (rc !is XPCOM.NS_OK) { | |
938 browser.dispose (); | |
939 error (rc); | |
940 } | |
941 factory.Release (); | |
942 | |
943 HelperAppLauncherDialogFactory dialogFactory = new HelperAppLauncherDialogFactory (); | |
944 dialogFactory.AddRef (); | |
945 aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CONTRACTID, true); | |
946 aClassName = MozillaDelegate.wcsToMbcs (null, "Helper App Launcher Dialog", true); //$NON-NLS-1$ | |
947 rc = componentRegistrar.RegisterFactory (XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CID, aClassName, aContractID, dialogFactory.getAddress ()); | |
948 if (rc !is XPCOM.NS_OK) { | |
949 browser.dispose (); | |
950 error (rc); | |
951 } | |
952 dialogFactory.Release (); | |
953 | |
954 /* | |
955 * This Download factory will be used if the GRE version is < 1.8. | |
956 * If the GRE version is 1.8.x then the Download factory that is registered later for | |
957 * contract "Transfer" will be used. | |
958 * If the GRE version is >= 1.9 then no Download factory is registered because this | |
959 * functionality is provided by the GRE. | |
960 */ | |
961 DownloadFactory downloadFactory = new DownloadFactory (); | |
962 downloadFactory.AddRef (); | |
963 aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOWNLOAD_CONTRACTID, true); | |
964 aClassName = MozillaDelegate.wcsToMbcs (null, "Download", true); //$NON-NLS-1$ | |
965 rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory.getAddress ()); | |
966 if (rc !is XPCOM.NS_OK) { | |
967 browser.dispose (); | |
968 error (rc); | |
969 } | |
970 downloadFactory.Release (); | |
971 | |
972 FilePickerFactory pickerFactory = IsXULRunner ? new FilePickerFactory_1_8 () : new FilePickerFactory (); | |
973 pickerFactory.AddRef (); | |
974 aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_FILEPICKER_CONTRACTID, true); | |
975 aClassName = MozillaDelegate.wcsToMbcs (null, "FilePicker", true); //$NON-NLS-1$ | |
976 rc = componentRegistrar.RegisterFactory (XPCOM.NS_FILEPICKER_CID, aClassName, aContractID, pickerFactory.getAddress ()); | |
977 if (rc !is XPCOM.NS_OK) { | |
978 browser.dispose (); | |
979 error (rc); | |
980 } | |
981 pickerFactory.Release (); | |
982 | |
983 componentRegistrar.Release (); | |
984 componentManager.Release (); | |
985 | |
986 Initialized = true; | |
987 } | |
988 | |
989 if (display.getData (DISPOSE_LISTENER_HOOKED) is null) { | |
990 display.setData (DISPOSE_LISTENER_HOOKED, DISPOSE_LISTENER_HOOKED); | |
991 display.addListener (DWT.Dispose, new Listener () { | |
992 public void handleEvent (Event event) { | |
993 if (BrowserCount > 0) return; /* another display is still active */ | |
994 | |
995 int /*long*/[] result = new int /*long*/[1]; | |
996 int rc = XPCOM.NS_GetServiceManager (result); | |
997 if (rc !is XPCOM.NS_OK) error (rc); | |
998 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
999 | |
1000 nsIServiceManager serviceManager = new nsIServiceManager (result[0]); | |
1001 result[0] = 0; | |
1002 byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true); | |
1003 rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result); | |
1004 if (rc !is XPCOM.NS_OK) error (rc); | |
1005 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1006 | |
1007 nsIObserverService observerService = new nsIObserverService (result[0]); | |
1008 result[0] = 0; | |
1009 buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_BEFORE_CHANGE, true); | |
1010 int length = SHUTDOWN_PERSIST.length (); | |
1011 char[] chars = new char [length + 1]; | |
1012 SHUTDOWN_PERSIST.getChars (0, length, chars, 0); | |
1013 rc = observerService.NotifyObservers (0, buffer, chars); | |
1014 if (rc !is XPCOM.NS_OK) error (rc); | |
1015 observerService.Release (); | |
1016 | |
1017 if (LocationProvider !is null) { | |
1018 String prefsLocation = LocationProvider.profilePath + AppFileLocProvider.PREFERENCES_FILE; | |
1019 nsEmbedString pathString = new nsEmbedString (prefsLocation); | |
1020 rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, result); | |
1021 if (rc !is XPCOM.NS_OK) Mozilla.error (rc); | |
1022 if (result[0] is 0) Mozilla.error (XPCOM.NS_ERROR_NULL_POINTER); | |
1023 pathString.dispose (); | |
1024 | |
1025 nsILocalFile localFile = new nsILocalFile (result [0]); | |
1026 result[0] = 0; | |
1027 rc = localFile.QueryInterface (nsIFile.NS_IFILE_IID, result); | |
1028 if (rc !is XPCOM.NS_OK) Mozilla.error (rc); | |
1029 if (result[0] is 0) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1030 localFile.Release (); | |
1031 | |
1032 nsIFile prefFile = new nsIFile (result[0]); | |
1033 result[0] = 0; | |
1034 | |
1035 buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true); | |
1036 rc = serviceManager.GetServiceByContractID (buffer, nsIPrefService.NS_IPREFSERVICE_IID, result); | |
1037 if (rc !is XPCOM.NS_OK) error (rc); | |
1038 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1039 | |
1040 nsIPrefService prefService = new nsIPrefService (result[0]); | |
1041 result[0] = 0; | |
1042 rc = prefService.SavePrefFile(prefFile.getAddress ()); | |
1043 prefService.Release (); | |
1044 prefFile.Release (); | |
1045 } | |
1046 serviceManager.Release (); | |
1047 | |
1048 if (XPCOMWasGlued) { | |
1049 XPCOM.XPCOMGlueShutdown (); | |
1050 XPCOMWasGlued = false; | |
1051 } | |
1052 if (XPCOMInitWasGlued) { | |
1053 XPCOMInit.XPCOMGlueShutdown (); | |
1054 XPCOMInitWasGlued = false; | |
1055 } | |
1056 Initialized = false; | |
1057 } | |
1058 }); | |
1059 } | |
1060 | |
1061 BrowserCount++; | |
1062 int rc = XPCOM.NS_GetComponentManager (result); | |
1063 if (rc !is XPCOM.NS_OK) { | |
1064 browser.dispose (); | |
1065 error (rc); | |
1066 } | |
1067 if (result[0] is 0) { | |
1068 browser.dispose (); | |
1069 error (XPCOM.NS_NOINTERFACE); | |
1070 } | |
1071 | |
1072 nsIComponentManager componentManager = new nsIComponentManager (result[0]); | |
1073 result[0] = 0; | |
1074 nsID NS_IWEBBROWSER_CID = new nsID ("F1EAC761-87E9-11d3-AF80-00A024FFC08C"); //$NON-NLS-1$ | |
1075 rc = componentManager.CreateInstance (NS_IWEBBROWSER_CID, 0, nsIWebBrowser.NS_IWEBBROWSER_IID, result); | |
1076 if (rc !is XPCOM.NS_OK) { | |
1077 browser.dispose (); | |
1078 error (rc); | |
1079 } | |
1080 if (result[0] is 0) { | |
1081 browser.dispose (); | |
1082 error (XPCOM.NS_NOINTERFACE); | |
1083 } | |
1084 | |
1085 webBrowser = new nsIWebBrowser (result[0]); | |
1086 result[0] = 0; | |
1087 | |
1088 createCOMInterfaces (); | |
1089 AddRef (); | |
1090 | |
1091 rc = webBrowser.SetContainerWindow (webBrowserChrome.getAddress()); | |
1092 if (rc !is XPCOM.NS_OK) { | |
1093 browser.dispose (); | |
1094 error (rc); | |
1095 } | |
1096 | |
1097 rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); | |
1098 if (rc !is XPCOM.NS_OK) { | |
1099 browser.dispose (); | |
1100 error (rc); | |
1101 } | |
1102 if (result[0] is 0) { | |
1103 browser.dispose (); | |
1104 error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1105 } | |
1106 | |
1107 nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); | |
1108 result[0] = 0; | |
1109 Rectangle rect = browser.getClientArea (); | |
1110 if (rect.isEmpty ()) { | |
1111 rect.width = 1; | |
1112 rect.height = 1; | |
1113 } | |
1114 | |
1115 embedHandle = delegate.getHandle (); | |
1116 | |
1117 rc = baseWindow.InitWindow (embedHandle, 0, 0, 0, rect.width, rect.height); | |
1118 if (rc !is XPCOM.NS_OK) { | |
1119 browser.dispose (); | |
1120 error (XPCOM.NS_ERROR_FAILURE); | |
1121 } | |
1122 rc = baseWindow.Create (); | |
1123 if (rc !is XPCOM.NS_OK) { | |
1124 browser.dispose (); | |
1125 error (XPCOM.NS_ERROR_FAILURE); | |
1126 } | |
1127 rc = baseWindow.SetVisibility (1); | |
1128 if (rc !is XPCOM.NS_OK) { | |
1129 browser.dispose (); | |
1130 error (XPCOM.NS_ERROR_FAILURE); | |
1131 } | |
1132 baseWindow.Release (); | |
1133 | |
1134 if (!PerformedVersionCheck) { | |
1135 PerformedVersionCheck = true; | |
1136 | |
1137 /* | |
1138 * Check for the availability of the pre-1.8 implementation of nsIDocShell | |
1139 * to determine if the GRE's version is < 1.8. | |
1140 */ | |
1141 rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result); | |
1142 if (rc !is XPCOM.NS_OK) { | |
1143 browser.dispose (); | |
1144 error (XPCOM.NS_ERROR_FAILURE); | |
1145 } | |
1146 if (result[0] is 0) { | |
1147 browser.dispose (); | |
1148 error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1149 } | |
1150 nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]); | |
1151 result[0] = 0; | |
1152 | |
1153 rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result); | |
1154 if (rc is XPCOM.NS_OK && result[0] !is 0) { | |
1155 IsPre_1_8 = true; | |
1156 new nsISupports (result[0]).Release (); | |
1157 } | |
1158 result[0] = 0; | |
1159 | |
1160 /* | |
1161 * A Download factory for contract "Transfer" must be registered iff the GRE's version is 1.8.x. | |
1162 * Check for the availability of the 1.8 implementation of nsIDocShell to determine if the | |
1163 * GRE's version is 1.8.x. | |
1164 * If the GRE version is < 1.8 then the previously-registered Download factory for contract | |
1165 * "Download" will be used. | |
1166 * If the GRE version is >= 1.9 then no Download factory is registered because this | |
1167 * functionality is provided by the GRE. | |
1168 */ | |
1169 if (!IsPre_1_8) { | |
1170 rc = interfaceRequestor.GetInterface (nsIDocShell_1_8.NS_IDOCSHELL_IID, result); | |
1171 if (rc is XPCOM.NS_OK && result[0] !is 0) { /* 1.8 */ | |
1172 new nsISupports (result[0]).Release (); | |
1173 result[0] = 0; | |
1174 rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result); | |
1175 if (rc !is XPCOM.NS_OK) { | |
1176 browser.dispose (); | |
1177 error (rc); | |
1178 } | |
1179 if (result[0] is 0) { | |
1180 browser.dispose (); | |
1181 error (XPCOM.NS_NOINTERFACE); | |
1182 } | |
1183 | |
1184 nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]); | |
1185 DownloadFactory_1_8 downloadFactory_1_8 = new DownloadFactory_1_8 (); | |
1186 downloadFactory_1_8.AddRef (); | |
1187 byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_TRANSFER_CONTRACTID, true); | |
1188 byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "Transfer", true); //$NON-NLS-1$ | |
1189 rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory_1_8.getAddress ()); | |
1190 if (rc !is XPCOM.NS_OK) { | |
1191 browser.dispose (); | |
1192 error (rc); | |
1193 } | |
1194 downloadFactory_1_8.Release (); | |
1195 componentRegistrar.Release (); | |
1196 } else { /* >= 1.9 */ | |
1197 /* | |
1198 * Bug in XULRunner 1.9. Mozilla no longer clears its background before initial content has | |
1199 * been set. As a result embedders appear broken if they do not immediately navigate to a url. | |
1200 * The workaround for this is to navigate to about:blank immediately so that the background is | |
1201 * cleared, but do not fire any corresponding events or allow Browser API calls to reveal this. | |
1202 * Once the client does a proper navigate with either setUrl() or setText() then resume as | |
1203 * normal. The Mozilla bug for this is https://bugzilla.mozilla.org/show_bug.cgi?id=415789. | |
1204 */ | |
1205 awaitingNavigate = true; | |
1206 rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1207 if (rc !is XPCOM.NS_OK) { | |
1208 browser.dispose (); | |
1209 error (rc); | |
1210 } | |
1211 if (result[0] is 0) { | |
1212 browser.dispose (); | |
1213 error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1214 } | |
1215 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1216 char[] uri = new char[ABOUT_BLANK.length () + 1]; | |
1217 ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uri, 0); | |
1218 rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0); | |
1219 webNavigation.Release (); | |
1220 } | |
1221 } | |
1222 result[0] = 0; | |
1223 interfaceRequestor.Release (); | |
1224 } | |
1225 componentManager.Release (); | |
1226 | |
1227 rc = webBrowser.AddWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID); | |
1228 if (rc !is XPCOM.NS_OK) { | |
1229 browser.dispose (); | |
1230 error (rc); | |
1231 } | |
1232 | |
1233 rc = webBrowser.SetParentURIContentListener (uriContentListener.getAddress ()); | |
1234 if (rc !is XPCOM.NS_OK) { | |
1235 browser.dispose (); | |
1236 error (rc); | |
1237 } | |
1238 | |
1239 delegate.init (); | |
1240 | |
1241 listener = new Listener () { | |
1242 public void handleEvent (Event event) { | |
1243 switch (event.type) { | |
1244 case DWT.Dispose: { | |
1245 /* make this handler run after other dispose listeners */ | |
1246 if (ignoreDispose) { | |
1247 ignoreDispose = false; | |
1248 break; | |
1249 } | |
1250 ignoreDispose = true; | |
1251 browser.notifyListeners (event.type, event); | |
1252 event.type = DWT.NONE; | |
1253 onDispose (event.display); | |
1254 break; | |
1255 } | |
1256 case DWT.Resize: onResize (); break; | |
1257 case DWT.FocusIn: Activate (); break; | |
1258 case DWT.Activate: Activate (); break; | |
1259 case DWT.Deactivate: { | |
1260 Display display = event.display; | |
1261 if (Mozilla.this.browser is display.getFocusControl ()) Deactivate (); | |
1262 break; | |
1263 } | |
1264 case DWT.Show: { | |
1265 /* | |
1266 * Feature in GTK Mozilla. Mozilla does not show up when | |
1267 * its container (a GTK fixed handle) is made visible | |
1268 * after having been hidden. The workaround is to reset | |
1269 * its size after the container has been made visible. | |
1270 */ | |
1271 Display display = event.display; | |
1272 display.asyncExec(new Runnable () { | |
1273 public void run() { | |
1274 if (browser.isDisposed ()) return; | |
1275 onResize (); | |
1276 } | |
1277 }); | |
1278 break; | |
1279 } | |
1280 } | |
1281 } | |
1282 }; | |
1283 int[] folderEvents = new int[] { | |
1284 DWT.Dispose, | |
1285 DWT.Resize, | |
1286 DWT.FocusIn, | |
1287 DWT.Activate, | |
1288 DWT.Deactivate, | |
1289 DWT.Show, | |
1290 DWT.KeyDown // needed to make browser traversable | |
1291 }; | |
1292 for (int i = 0; i < folderEvents.length; i++) { | |
1293 browser.addListener (folderEvents[i], listener); | |
1294 } | |
1295 } | |
1296 | |
1297 public bool back () { | |
1298 if (awaitingNavigate) return false; | |
1299 | |
1300 int /*long*/[] result = new int /*long*/[1]; | |
1301 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1302 if (rc !is XPCOM.NS_OK) error (rc); | |
1303 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1304 | |
1305 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1306 rc = webNavigation.GoBack (); | |
1307 webNavigation.Release (); | |
1308 return rc is XPCOM.NS_OK; | |
1309 } | |
1310 | |
1311 void createCOMInterfaces () { | |
1312 // Create each of the interfaces that this object implements | |
1313 supports = new XPCOMObject (new int[] {2, 0, 0}) { | |
1314 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1315 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1316 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1317 }; | |
1318 | |
1319 weakReference = new XPCOMObject (new int[] {2, 0, 0, 2}) { | |
1320 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1321 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1322 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1323 public int /*long*/ method3 (int /*long*/[] args) {return QueryReferent (args[0], args[1]);} | |
1324 }; | |
1325 | |
1326 webProgressListener = new XPCOMObject (new int[] {2, 0, 0, 4, 6, 3, 4, 3}) { | |
1327 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1328 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1329 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1330 public int /*long*/ method3 (int /*long*/[] args) {return OnStateChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3]);} | |
1331 public int /*long*/ method4 (int /*long*/[] args) {return OnProgressChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4], (int)/*64*/args[5]);} | |
1332 public int /*long*/ method5 (int /*long*/[] args) {return OnLocationChange (args[0], args[1], args[2]);} | |
1333 public int /*long*/ method6 (int /*long*/[] args) {return OnStatusChange (args[0], args[1], (int)/*64*/args[2], args[3]);} | |
1334 public int /*long*/ method7 (int /*long*/[] args) {return OnSecurityChange (args[0], args[1], (int)/*64*/args[2]);} | |
1335 }; | |
1336 | |
1337 webBrowserChrome = new XPCOMObject (new int[] {2, 0, 0, 2, 1, 1, 1, 1, 0, 2, 0, 1, 1}) { | |
1338 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1339 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1340 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1341 public int /*long*/ method3 (int /*long*/[] args) {return SetStatus ((int)/*64*/args[0], args[1]);} | |
1342 public int /*long*/ method4 (int /*long*/[] args) {return GetWebBrowser (args[0]);} | |
1343 public int /*long*/ method5 (int /*long*/[] args) {return SetWebBrowser (args[0]);} | |
1344 public int /*long*/ method6 (int /*long*/[] args) {return GetChromeFlags (args[0]);} | |
1345 public int /*long*/ method7 (int /*long*/[] args) {return SetChromeFlags ((int)/*64*/args[0]);} | |
1346 public int /*long*/ method8 (int /*long*/[] args) {return DestroyBrowserWindow ();} | |
1347 public int /*long*/ method9 (int /*long*/[] args) {return SizeBrowserTo ((int)/*64*/args[0], (int)/*64*/args[1]);} | |
1348 public int /*long*/ method10 (int /*long*/[] args) {return ShowAsModal ();} | |
1349 public int /*long*/ method11 (int /*long*/[] args) {return IsWindowModal (args[0]);} | |
1350 public int /*long*/ method12 (int /*long*/[] args) {return ExitModalEventLoop ((int)/*64*/args[0]);} | |
1351 }; | |
1352 | |
1353 webBrowserChromeFocus = new XPCOMObject (new int[] {2, 0, 0, 0, 0}) { | |
1354 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1355 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1356 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1357 public int /*long*/ method3 (int /*long*/[] args) {return FocusNextElement ();} | |
1358 public int /*long*/ method4 (int /*long*/[] args) {return FocusPrevElement ();} | |
1359 }; | |
1360 | |
1361 embeddingSiteWindow = new XPCOMObject (new int[] {2, 0, 0, 5, 5, 0, 1, 1, 1, 1, 1}) { | |
1362 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1363 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1364 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1365 public int /*long*/ method3 (int /*long*/[] args) {return SetDimensions ((int)/*64*/args[0], (int)/*64*/args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4]);} | |
1366 public int /*long*/ method4 (int /*long*/[] args) {return GetDimensions ((int)/*64*/args[0], args[1], args[2], args[3], args[4]);} | |
1367 public int /*long*/ method5 (int /*long*/[] args) {return SetFocus ();} | |
1368 public int /*long*/ method6 (int /*long*/[] args) {return GetVisibility (args[0]);} | |
1369 public int /*long*/ method7 (int /*long*/[] args) {return SetVisibility ((int)/*64*/args[0]);} | |
1370 public int /*long*/ method8 (int /*long*/[] args) {return GetTitle (args[0]);} | |
1371 public int /*long*/ method9 (int /*long*/[] args) {return SetTitle (args[0]);} | |
1372 public int /*long*/ method10 (int /*long*/[] args) {return GetSiteWindow (args[0]);} | |
1373 }; | |
1374 | |
1375 interfaceRequestor = new XPCOMObject (new int[] {2, 0, 0, 2} ){ | |
1376 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1377 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1378 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1379 public int /*long*/ method3 (int /*long*/[] args) {return GetInterface (args[0], args[1]);} | |
1380 }; | |
1381 | |
1382 supportsWeakReference = new XPCOMObject (new int[] {2, 0, 0, 1}) { | |
1383 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1384 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1385 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1386 public int /*long*/ method3 (int /*long*/[] args) {return GetWeakReference (args[0]);} | |
1387 }; | |
1388 | |
1389 contextMenuListener = new XPCOMObject (new int[] {2, 0, 0, 3}) { | |
1390 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1391 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1392 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1393 public int /*long*/ method3 (int /*long*/[] args) {return OnShowContextMenu ((int)/*64*/args[0], args[1], args[2]);} | |
1394 }; | |
1395 | |
1396 uriContentListener = new XPCOMObject (new int[] {2, 0, 0, 2, 5, 3, 4, 1, 1, 1, 1}) { | |
1397 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1398 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1399 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1400 public int /*long*/ method3 (int /*long*/[] args) {return OnStartURIOpen (args[0], args[1]);} | |
1401 public int /*long*/ method4 (int /*long*/[] args) {return DoContent (args[0], (int)/*64*/args[1], args[2], args[3], args[4]);} | |
1402 public int /*long*/ method5 (int /*long*/[] args) {return IsPreferred (args[0], args[1], args[2]);} | |
1403 public int /*long*/ method6 (int /*long*/[] args) {return CanHandleContent (args[0], (int)/*64*/args[1], args[2], args[3]);} | |
1404 public int /*long*/ method7 (int /*long*/[] args) {return GetLoadCookie (args[0]);} | |
1405 public int /*long*/ method8 (int /*long*/[] args) {return SetLoadCookie (args[0]);} | |
1406 public int /*long*/ method9 (int /*long*/[] args) {return GetParentContentListener (args[0]);} | |
1407 public int /*long*/ method10 (int /*long*/[] args) {return SetParentContentListener (args[0]);} | |
1408 }; | |
1409 | |
1410 tooltipListener = new XPCOMObject (new int[] {2, 0, 0, 3, 0}) { | |
1411 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1412 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1413 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1414 public int /*long*/ method3 (int /*long*/[] args) {return OnShowTooltip ((int)/*64*/args[0], (int)/*64*/args[1], args[2]);} | |
1415 public int /*long*/ method4 (int /*long*/[] args) {return OnHideTooltip ();} | |
1416 }; | |
1417 | |
1418 domEventListener = new XPCOMObject (new int[] {2, 0, 0, 1}) { | |
1419 public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} | |
1420 public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} | |
1421 public int /*long*/ method2 (int /*long*/[] args) {return Release ();} | |
1422 public int /*long*/ method3 (int /*long*/[] args) {return HandleEvent (args[0]);} | |
1423 }; | |
1424 } | |
1425 | |
1426 void disposeCOMInterfaces () { | |
1427 if (supports !is null) { | |
1428 supports.dispose (); | |
1429 supports = null; | |
1430 } | |
1431 if (weakReference !is null) { | |
1432 weakReference.dispose (); | |
1433 weakReference = null; | |
1434 } | |
1435 if (webProgressListener !is null) { | |
1436 webProgressListener.dispose (); | |
1437 webProgressListener = null; | |
1438 } | |
1439 if (webBrowserChrome !is null) { | |
1440 webBrowserChrome.dispose (); | |
1441 webBrowserChrome = null; | |
1442 } | |
1443 if (webBrowserChromeFocus !is null) { | |
1444 webBrowserChromeFocus.dispose (); | |
1445 webBrowserChromeFocus = null; | |
1446 } | |
1447 if (embeddingSiteWindow !is null) { | |
1448 embeddingSiteWindow.dispose (); | |
1449 embeddingSiteWindow = null; | |
1450 } | |
1451 if (interfaceRequestor !is null) { | |
1452 interfaceRequestor.dispose (); | |
1453 interfaceRequestor = null; | |
1454 } | |
1455 if (supportsWeakReference !is null) { | |
1456 supportsWeakReference.dispose (); | |
1457 supportsWeakReference = null; | |
1458 } | |
1459 if (contextMenuListener !is null) { | |
1460 contextMenuListener.dispose (); | |
1461 contextMenuListener = null; | |
1462 } | |
1463 if (uriContentListener !is null) { | |
1464 uriContentListener.dispose (); | |
1465 uriContentListener = null; | |
1466 } | |
1467 if (tooltipListener !is null) { | |
1468 tooltipListener.dispose (); | |
1469 tooltipListener = null; | |
1470 } | |
1471 if (domEventListener !is null) { | |
1472 domEventListener.dispose (); | |
1473 domEventListener = null; | |
1474 } | |
1475 } | |
1476 | |
1477 public bool execute (String script) { | |
1478 if (awaitingNavigate) return false; | |
1479 | |
1480 String url = PREFIX_JAVASCRIPT + script + ";void(0);"; //$NON-NLS-1$ | |
1481 int /*long*/[] result = new int /*long*/[1]; | |
1482 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1483 if (rc !is XPCOM.NS_OK) error (rc); | |
1484 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1485 | |
1486 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1487 char[] arg = url.toCharArray (); | |
1488 char[] c = new char[arg.length+1]; | |
1489 System.arraycopy (arg, 0, c, 0, arg.length); | |
1490 rc = webNavigation.LoadURI (c, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0); | |
1491 webNavigation.Release (); | |
1492 return rc is XPCOM.NS_OK; | |
1493 } | |
1494 | |
1495 static Browser findBrowser (int /*long*/ handle) { | |
1496 return MozillaDelegate.findBrowser (handle); | |
1497 } | |
1498 | |
1499 public bool forward () { | |
1500 if (awaitingNavigate) return false; | |
1501 | |
1502 int /*long*/[] result = new int /*long*/[1]; | |
1503 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1504 if (rc !is XPCOM.NS_OK) error (rc); | |
1505 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1506 | |
1507 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1508 rc = webNavigation.GoForward (); | |
1509 webNavigation.Release (); | |
1510 | |
1511 return rc is XPCOM.NS_OK; | |
1512 } | |
1513 | |
1514 public String getText () { | |
1515 if (awaitingNavigate) return ""; //$NON-NLS-1$ | |
1516 | |
1517 int /*long*/[] result = new int /*long*/[1]; | |
1518 int rc = webBrowser.GetContentDOMWindow (result); | |
1519 if (rc !is XPCOM.NS_OK) error (rc); | |
1520 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1521 | |
1522 nsIDOMWindow window = new nsIDOMWindow (result[0]); | |
1523 result[0] = 0; | |
1524 rc = window.GetDocument (result); | |
1525 if (rc !is XPCOM.NS_OK) error (rc); | |
1526 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1527 window.Release (); | |
1528 | |
1529 int /*long*/ document = result[0]; | |
1530 result[0] = 0; | |
1531 rc = XPCOM.NS_GetComponentManager (result); | |
1532 if (rc !is XPCOM.NS_OK) error (rc); | |
1533 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1534 | |
1535 nsIComponentManager componentManager = new nsIComponentManager (result[0]); | |
1536 result[0] = 0; | |
1537 byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOMSERIALIZER_CONTRACTID, true); | |
1538 char[] chars = null; | |
1539 | |
1540 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIDOMSerializer_1_7.NS_IDOMSERIALIZER_IID, result); | |
1541 if (rc is XPCOM.NS_OK) { /* mozilla >= 1.7 */ | |
1542 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1543 | |
1544 nsIDOMSerializer_1_7 serializer = new nsIDOMSerializer_1_7 (result[0]); | |
1545 result[0] = 0; | |
1546 int /*long*/ string = XPCOM.nsEmbedString_new (); | |
1547 rc = serializer.SerializeToString (document, string); | |
1548 serializer.Release (); | |
1549 | |
1550 int length = XPCOM.nsEmbedString_Length (string); | |
1551 int /*long*/ buffer = XPCOM.nsEmbedString_get (string); | |
1552 chars = new char[length]; | |
1553 XPCOM.memmove (chars, buffer, length * 2); | |
1554 XPCOM.nsEmbedString_delete (string); | |
1555 } else { /* mozilla < 1.7 */ | |
1556 rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIDOMSerializer.NS_IDOMSERIALIZER_IID, result); | |
1557 if (rc !is XPCOM.NS_OK) error (rc); | |
1558 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1559 | |
1560 nsIDOMSerializer serializer = new nsIDOMSerializer (result[0]); | |
1561 result[0] = 0; | |
1562 rc = serializer.SerializeToString (document, result); | |
1563 serializer.Release (); | |
1564 | |
1565 int length = XPCOM.strlen_PRUnichar (result[0]); | |
1566 chars = new char[length]; | |
1567 XPCOM.memmove (chars, result[0], length * 2); | |
1568 } | |
1569 | |
1570 componentManager.Release (); | |
1571 new nsISupports (document).Release (); | |
1572 return new String (chars); | |
1573 } | |
1574 | |
1575 public String getUrl () { | |
1576 if (awaitingNavigate) return ""; //$NON-NLS-1$ | |
1577 | |
1578 int /*long*/[] result = new int /*long*/[1]; | |
1579 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1580 if (rc !is XPCOM.NS_OK) error (rc); | |
1581 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1582 | |
1583 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1584 int /*long*/[] aCurrentURI = new int /*long*/[1]; | |
1585 rc = webNavigation.GetCurrentURI (aCurrentURI); | |
1586 if (rc !is XPCOM.NS_OK) error (rc); | |
1587 webNavigation.Release (); | |
1588 | |
1589 byte[] dest = null; | |
1590 if (aCurrentURI[0] !is 0) { | |
1591 nsIURI uri = new nsIURI (aCurrentURI[0]); | |
1592 int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); | |
1593 rc = uri.GetSpec (aSpec); | |
1594 if (rc !is XPCOM.NS_OK) error (rc); | |
1595 int length = XPCOM.nsEmbedCString_Length (aSpec); | |
1596 int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec); | |
1597 dest = new byte[length]; | |
1598 XPCOM.memmove (dest, buffer, length); | |
1599 XPCOM.nsEmbedCString_delete (aSpec); | |
1600 uri.Release (); | |
1601 } | |
1602 if (dest is null) return ""; //$NON-NLS-1$ | |
1603 | |
1604 String location = new String (dest); | |
1605 /* | |
1606 * If the URI indicates that the page is being rendered from memory | |
1607 * (via setText()) then set it to about:blank to be consistent with IE. | |
1608 */ | |
1609 if (location.equals (URI_FROMMEMORY)) location = ABOUT_BLANK; | |
1610 return location; | |
1611 } | |
1612 | |
1613 public Object getWebBrowser () { | |
1614 if ((browser.getStyle () & DWT.MOZILLA) is 0) return null; | |
1615 if (webBrowserObject !is null) return webBrowserObject; | |
1616 | |
1617 try { | |
1618 Class clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$ | |
1619 Method method = clazz.getMethod ("getInstance", new Class[0]); //$NON-NLS-1$ | |
1620 Object mozilla = method.invoke (null, new Object[0]); | |
1621 method = clazz.getMethod ("wrapXPCOMObject", new Class[] {Long.TYPE, String.class}); //$NON-NLS-1$ | |
1622 webBrowserObject = method.invoke (mozilla, new Object[] {new Long (webBrowser.getAddress ()), nsIWebBrowser.NS_IWEBBROWSER_IID_STR}); | |
1623 /* | |
1624 * The following AddRef() is needed to offset the automatic Release() that | |
1625 * will be performed by JavaXPCOM when webBrowserObject is finalized. | |
1626 */ | |
1627 webBrowser.AddRef (); | |
1628 return webBrowserObject; | |
1629 } catch (ClassNotFoundException e) { | |
1630 } catch (NoSuchMethodException e) { | |
1631 } catch (IllegalArgumentException e) { | |
1632 } catch (IllegalAccessException e) { | |
1633 } catch (InvocationTargetException e) { | |
1634 } | |
1635 return null; | |
1636 } | |
1637 | |
1638 public bool isBackEnabled () { | |
1639 if (awaitingNavigate) return false; | |
1640 | |
1641 int /*long*/[] result = new int /*long*/[1]; | |
1642 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1643 if (rc !is XPCOM.NS_OK) error (rc); | |
1644 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1645 | |
1646 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1647 int[] aCanGoBack = new int[1]; /* PRBool */ | |
1648 rc = webNavigation.GetCanGoBack (aCanGoBack); | |
1649 webNavigation.Release (); | |
1650 return aCanGoBack[0] !is 0; | |
1651 } | |
1652 | |
1653 public bool isForwardEnabled () { | |
1654 if (awaitingNavigate) return false; | |
1655 | |
1656 int /*long*/[] result = new int /*long*/[1]; | |
1657 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1658 if (rc !is XPCOM.NS_OK) error (rc); | |
1659 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1660 | |
1661 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1662 int[] aCanGoForward = new int[1]; /* PRBool */ | |
1663 rc = webNavigation.GetCanGoForward (aCanGoForward); | |
1664 webNavigation.Release (); | |
1665 return aCanGoForward[0] !is 0; | |
1666 } | |
1667 | |
1668 static String error (int code) { | |
1669 throw new DWTError ("XPCOM error " + code); //$NON-NLS-1$ | |
1670 } | |
1671 | |
1672 void onDispose (Display display) { | |
1673 int rc = webBrowser.RemoveWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID); | |
1674 if (rc !is XPCOM.NS_OK) error (rc); | |
1675 | |
1676 rc = webBrowser.SetParentURIContentListener (0); | |
1677 if (rc !is XPCOM.NS_OK) error (rc); | |
1678 | |
1679 unhookDOMListeners (); | |
1680 if (listener !is null) { | |
1681 int[] folderEvents = new int[] { | |
1682 DWT.Dispose, | |
1683 DWT.Resize, | |
1684 DWT.FocusIn, | |
1685 DWT.Activate, | |
1686 DWT.Deactivate, | |
1687 DWT.Show, | |
1688 DWT.KeyDown, | |
1689 }; | |
1690 for (int i = 0; i < folderEvents.length; i++) { | |
1691 browser.removeListener (folderEvents[i], listener); | |
1692 } | |
1693 listener = null; | |
1694 } | |
1695 | |
1696 int /*long*/[] result = new int /*long*/[1]; | |
1697 rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); | |
1698 if (rc !is XPCOM.NS_OK) error (rc); | |
1699 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1700 | |
1701 nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); | |
1702 rc = baseWindow.Destroy (); | |
1703 if (rc !is XPCOM.NS_OK) error (rc); | |
1704 baseWindow.Release (); | |
1705 | |
1706 Release (); | |
1707 webBrowser.Release (); | |
1708 webBrowser = null; | |
1709 webBrowserObject = null; | |
1710 | |
1711 if (tip !is null && !tip.isDisposed ()) tip.dispose (); | |
1712 tip = null; | |
1713 location = size = null; | |
1714 | |
1715 Enumeration elements = unhookedDOMWindows.elements (); | |
1716 while (elements.hasMoreElements ()) { | |
1717 LONG ptrObject = (LONG)elements.nextElement (); | |
1718 new nsISupports (ptrObject.value).Release (); | |
1719 } | |
1720 unhookedDOMWindows = null; | |
1721 | |
1722 delegate.onDispose (embedHandle); | |
1723 delegate = null; | |
1724 | |
1725 embedHandle = 0; | |
1726 BrowserCount--; | |
1727 } | |
1728 | |
1729 void Activate () { | |
1730 int /*long*/[] result = new int /*long*/[1]; | |
1731 int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result); | |
1732 if (rc !is XPCOM.NS_OK) error (rc); | |
1733 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1734 | |
1735 nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]); | |
1736 rc = webBrowserFocus.Activate (); | |
1737 if (rc !is XPCOM.NS_OK) error (rc); | |
1738 webBrowserFocus.Release (); | |
1739 } | |
1740 | |
1741 void Deactivate () { | |
1742 int /*long*/[] result = new int /*long*/[1]; | |
1743 int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result); | |
1744 if (rc !is XPCOM.NS_OK) error (rc); | |
1745 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1746 | |
1747 nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]); | |
1748 rc = webBrowserFocus.Deactivate (); | |
1749 if (rc !is XPCOM.NS_OK) error (rc); | |
1750 webBrowserFocus.Release (); | |
1751 } | |
1752 | |
1753 void onResize () { | |
1754 Rectangle rect = browser.getClientArea (); | |
1755 int width = Math.max (1, rect.width); | |
1756 int height = Math.max (1, rect.height); | |
1757 | |
1758 int /*long*/[] result = new int /*long*/[1]; | |
1759 int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); | |
1760 if (rc !is XPCOM.NS_OK) error (rc); | |
1761 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1762 | |
1763 delegate.setSize (embedHandle, width, height); | |
1764 nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); | |
1765 rc = baseWindow.SetPositionAndSize (0, 0, width, height, 1); | |
1766 if (rc !is XPCOM.NS_OK) error (rc); | |
1767 baseWindow.Release (); | |
1768 } | |
1769 | |
1770 public void refresh () { | |
1771 if (awaitingNavigate) return; | |
1772 | |
1773 int /*long*/[] result = new int /*long*/[1]; | |
1774 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1775 if (rc !is XPCOM.NS_OK) error(rc); | |
1776 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1777 | |
1778 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1779 rc = webNavigation.Reload (nsIWebNavigation.LOAD_FLAGS_NONE); | |
1780 webNavigation.Release (); | |
1781 if (rc is XPCOM.NS_OK) return; | |
1782 /* | |
1783 * Feature in Mozilla. Reload returns an error code NS_ERROR_INVALID_POINTER | |
1784 * when it is called immediately after a request to load a new document using | |
1785 * LoadURI. The workaround is to ignore this error code. | |
1786 * | |
1787 * Feature in Mozilla. Attempting to reload a file that no longer exists | |
1788 * returns an error code of NS_ERROR_FILE_NOT_FOUND. This is equivalent to | |
1789 * attempting to load a non-existent local url, which is not a Browser error, | |
1790 * so this error code should be ignored. | |
1791 */ | |
1792 if (rc !is XPCOM.NS_ERROR_INVALID_POINTER && rc !is XPCOM.NS_ERROR_FILE_NOT_FOUND) error (rc); | |
1793 } | |
1794 | |
1795 public bool setText (String html) { | |
1796 /* | |
1797 * Feature in Mozilla. The focus memory of Mozilla must be | |
1798 * properly managed through the nsIWebBrowserFocus interface. | |
1799 * In particular, nsIWebBrowserFocus.deactivate must be called | |
1800 * when the focus moves from the browser (or one of its children | |
1801 * managed by Mozilla to another widget. We currently do not | |
1802 * get notified when a widget takes focus away from the Browser. | |
1803 * As a result, deactivate is not properly called. This causes | |
1804 * Mozilla to retake focus the next time a document is loaded. | |
1805 * This breaks the case where the HTML loaded in the Browser | |
1806 * varies while the user enters characters in a text widget. The text | |
1807 * widget loses focus every time new content is loaded. | |
1808 * The current workaround is to call deactivate everytime if | |
1809 * the browser currently does not have focus. A better workaround | |
1810 * would be to have a way to call deactivate when the Browser | |
1811 * or one of its children loses focus. | |
1812 */ | |
1813 if (browser !is browser.getDisplay ().getFocusControl ()) Deactivate (); | |
1814 | |
1815 /* convert the String containing HTML to an array of bytes with UTF-8 data */ | |
1816 byte[] data = null; | |
1817 try { | |
1818 data = html.getBytes ("UTF-8"); //$NON-NLS-1$ | |
1819 } catch (UnsupportedEncodingException e) { | |
1820 return false; | |
1821 } | |
1822 | |
1823 awaitingNavigate = false; | |
1824 | |
1825 byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$ | |
1826 int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length); | |
1827 byte[] contentCharsetBuffer = MozillaDelegate.wcsToMbcs (null, "UTF-8", true); //$NON-NLS-1$ | |
1828 int /*long*/ aContentCharset = XPCOM.nsEmbedCString_new (contentCharsetBuffer, contentCharsetBuffer.length); | |
1829 | |
1830 int /*long*/[] result = new int /*long*/[1]; | |
1831 int rc = XPCOM.NS_GetServiceManager (result); | |
1832 if (rc !is XPCOM.NS_OK) error (rc); | |
1833 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1834 | |
1835 nsIServiceManager serviceManager = new nsIServiceManager (result[0]); | |
1836 result[0] = 0; | |
1837 rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result); | |
1838 if (rc !is XPCOM.NS_OK) error (rc); | |
1839 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1840 serviceManager.Release (); | |
1841 | |
1842 nsIIOService ioService = new nsIIOService (result[0]); | |
1843 result[0] = 0; | |
1844 /* | |
1845 * Note. Mozilla ignores LINK tags used to load CSS stylesheets | |
1846 * when the URI protocol for the nsInputStreamChannel | |
1847 * is about:blank. The fix is to specify the file protocol. | |
1848 */ | |
1849 byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, false); | |
1850 int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length); | |
1851 rc = ioService.NewURI (aSpec, null, 0, result); | |
1852 if (rc !is XPCOM.NS_OK) error (rc); | |
1853 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
1854 XPCOM.nsEmbedCString_delete (aSpec); | |
1855 ioService.Release (); | |
1856 | |
1857 nsIURI uri = new nsIURI (result[0]); | |
1858 result[0] = 0; | |
1859 | |
1860 rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result); | |
1861 if (rc !is XPCOM.NS_OK) error (rc); | |
1862 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1863 nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]); | |
1864 result[0] = 0; | |
1865 | |
1866 /* | |
1867 * Feature in Mozilla. LoadStream invokes the nsIInputStream argument | |
1868 * through a different thread. The callback mechanism must attach | |
1869 * a non java thread to the JVM otherwise the nsIInputStream Read and | |
1870 * Close methods never get called. | |
1871 */ | |
1872 InputStream inputStream = new InputStream (data); | |
1873 inputStream.AddRef (); | |
1874 | |
1875 rc = interfaceRequestor.GetInterface (nsIDocShell_1_9.NS_IDOCSHELL_IID, result); | |
1876 if (rc is XPCOM.NS_OK) { | |
1877 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1878 nsIDocShell_1_9 docShell = new nsIDocShell_1_9 (result[0]); | |
1879 rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0); | |
1880 docShell.Release (); | |
1881 } else { | |
1882 result[0] = 0; | |
1883 rc = interfaceRequestor.GetInterface (nsIDocShell_1_8.NS_IDOCSHELL_IID, result); | |
1884 if (rc is XPCOM.NS_OK) { | |
1885 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1886 nsIDocShell_1_8 docShell = new nsIDocShell_1_8 (result[0]); | |
1887 rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0); | |
1888 docShell.Release (); | |
1889 } else { | |
1890 result[0] = 0; | |
1891 rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result); | |
1892 if (rc !is XPCOM.NS_OK) error (rc); | |
1893 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1894 nsIDocShell docShell = new nsIDocShell (result[0]); | |
1895 rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0); | |
1896 docShell.Release (); | |
1897 } | |
1898 } | |
1899 if (rc !is XPCOM.NS_OK) error (rc); | |
1900 result[0] = 0; | |
1901 | |
1902 inputStream.Release (); | |
1903 interfaceRequestor.Release (); | |
1904 uri.Release (); | |
1905 XPCOM.nsEmbedCString_delete (aContentCharset); | |
1906 XPCOM.nsEmbedCString_delete (aContentType); | |
1907 return true; | |
1908 } | |
1909 | |
1910 public bool setUrl (String url) { | |
1911 awaitingNavigate = false; | |
1912 | |
1913 int /*long*/[] result = new int /*long*/[1]; | |
1914 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1915 if (rc !is XPCOM.NS_OK) error (rc); | |
1916 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1917 | |
1918 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1919 char[] uri = new char[url.length () + 1]; | |
1920 url.getChars (0, url.length (), uri, 0); | |
1921 rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0); | |
1922 webNavigation.Release (); | |
1923 return rc is XPCOM.NS_OK; | |
1924 } | |
1925 | |
1926 public void stop () { | |
1927 if (awaitingNavigate) return; | |
1928 | |
1929 int /*long*/[] result = new int /*long*/[1]; | |
1930 int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); | |
1931 if (rc !is XPCOM.NS_OK) error (rc); | |
1932 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1933 | |
1934 nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); | |
1935 rc = webNavigation.Stop (nsIWebNavigation.STOP_ALL); | |
1936 if (rc !is XPCOM.NS_OK) error (rc); | |
1937 webNavigation.Release (); | |
1938 } | |
1939 | |
1940 void hookDOMListeners (nsIDOMEventTarget target, bool isTop) { | |
1941 nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS); | |
1942 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1943 string.dispose (); | |
1944 string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD); | |
1945 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1946 string.dispose (); | |
1947 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN); | |
1948 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1949 string.dispose (); | |
1950 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP); | |
1951 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1952 string.dispose (); | |
1953 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE); | |
1954 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1955 string.dispose (); | |
1956 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL); | |
1957 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1958 string.dispose (); | |
1959 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG); | |
1960 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1961 string.dispose (); | |
1962 | |
1963 /* | |
1964 * Only hook mouseover and mouseout if the target is a top-level frame, so that mouse moves | |
1965 * between frames will not generate events. | |
1966 */ | |
1967 if (isTop && delegate.hookEnterExit ()) { | |
1968 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER); | |
1969 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1970 string.dispose (); | |
1971 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT); | |
1972 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1973 string.dispose (); | |
1974 } | |
1975 | |
1976 string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN); | |
1977 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1978 string.dispose (); | |
1979 string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS); | |
1980 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1981 string.dispose (); | |
1982 string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP); | |
1983 target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
1984 string.dispose (); | |
1985 } | |
1986 | |
1987 void unhookDOMListeners () { | |
1988 int /*long*/[] result = new int /*long*/[1]; | |
1989 int rc = webBrowser.GetContentDOMWindow (result); | |
1990 if (rc !is XPCOM.NS_OK) error (rc); | |
1991 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1992 | |
1993 nsIDOMWindow window = new nsIDOMWindow (result[0]); | |
1994 result[0] = 0; | |
1995 rc = window.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result); | |
1996 if (rc !is XPCOM.NS_OK) error (rc); | |
1997 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
1998 | |
1999 nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); | |
2000 result[0] = 0; | |
2001 unhookDOMListeners (target); | |
2002 target.Release (); | |
2003 | |
2004 /* Listeners must be unhooked in pages contained in frames */ | |
2005 rc = window.GetFrames (result); | |
2006 if (rc !is XPCOM.NS_OK) error (rc); | |
2007 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2008 nsIDOMWindowCollection frames = new nsIDOMWindowCollection (result[0]); | |
2009 result[0] = 0; | |
2010 int[] frameCount = new int[1]; | |
2011 rc = frames.GetLength (frameCount); /* PRUint32 */ | |
2012 if (rc !is XPCOM.NS_OK) error (rc); | |
2013 int count = frameCount[0]; | |
2014 | |
2015 if (count > 0) { | |
2016 for (int i = 0; i < count; i++) { | |
2017 rc = frames.Item (i, result); | |
2018 if (rc !is XPCOM.NS_OK) error (rc); | |
2019 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2020 | |
2021 nsIDOMWindow frame = new nsIDOMWindow (result[0]); | |
2022 result[0] = 0; | |
2023 rc = frame.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result); | |
2024 if (rc !is XPCOM.NS_OK) error (rc); | |
2025 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2026 | |
2027 target = new nsIDOMEventTarget (result[0]); | |
2028 result[0] = 0; | |
2029 unhookDOMListeners (target); | |
2030 target.Release (); | |
2031 frame.Release (); | |
2032 } | |
2033 } | |
2034 frames.Release (); | |
2035 window.Release (); | |
2036 } | |
2037 | |
2038 void unhookDOMListeners (nsIDOMEventTarget target) { | |
2039 nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS); | |
2040 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2041 string.dispose (); | |
2042 string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD); | |
2043 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2044 string.dispose (); | |
2045 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN); | |
2046 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2047 string.dispose (); | |
2048 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP); | |
2049 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2050 string.dispose (); | |
2051 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE); | |
2052 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2053 string.dispose (); | |
2054 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL); | |
2055 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2056 string.dispose (); | |
2057 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG); | |
2058 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2059 string.dispose (); | |
2060 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER); | |
2061 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2062 string.dispose (); | |
2063 string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT); | |
2064 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2065 string.dispose (); | |
2066 string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN); | |
2067 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2068 string.dispose (); | |
2069 string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS); | |
2070 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2071 string.dispose (); | |
2072 string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP); | |
2073 target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); | |
2074 string.dispose (); | |
2075 } | |
2076 | |
2077 /* nsISupports */ | |
2078 | |
2079 int QueryInterface (int /*long*/ riid, int /*long*/ ppvObject) { | |
2080 if (riid is 0 || ppvObject is 0) return XPCOM.NS_ERROR_NO_INTERFACE; | |
2081 | |
2082 nsID guid = new nsID (); | |
2083 XPCOM.memmove (guid, riid, nsID.sizeof); | |
2084 | |
2085 if (guid.Equals (nsISupports.NS_ISUPPORTS_IID)) { | |
2086 XPCOM.memmove (ppvObject, new int /*long*/[] {supports.getAddress ()}, C.PTR_SIZEOF); | |
2087 AddRef (); | |
2088 return XPCOM.NS_OK; | |
2089 } | |
2090 if (guid.Equals (nsIWeakReference.NS_IWEAKREFERENCE_IID)) { | |
2091 XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF); | |
2092 AddRef (); | |
2093 return XPCOM.NS_OK; | |
2094 } | |
2095 if (guid.Equals (nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID)) { | |
2096 XPCOM.memmove (ppvObject, new int /*long*/[] {webProgressListener.getAddress ()}, C.PTR_SIZEOF); | |
2097 AddRef (); | |
2098 return XPCOM.NS_OK; | |
2099 } | |
2100 if (guid.Equals (nsIWebBrowserChrome.NS_IWEBBROWSERCHROME_IID)) { | |
2101 XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChrome.getAddress ()}, C.PTR_SIZEOF); | |
2102 AddRef (); | |
2103 return XPCOM.NS_OK; | |
2104 } | |
2105 if (guid.Equals (nsIWebBrowserChromeFocus.NS_IWEBBROWSERCHROMEFOCUS_IID)) { | |
2106 XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChromeFocus.getAddress ()}, C.PTR_SIZEOF); | |
2107 AddRef (); | |
2108 return XPCOM.NS_OK; | |
2109 } | |
2110 if (guid.Equals (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID)) { | |
2111 XPCOM.memmove (ppvObject, new int /*long*/[] {embeddingSiteWindow.getAddress ()}, C.PTR_SIZEOF); | |
2112 AddRef (); | |
2113 return XPCOM.NS_OK; | |
2114 } | |
2115 if (guid.Equals (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID)) { | |
2116 XPCOM.memmove (ppvObject, new int /*long*/[] {interfaceRequestor.getAddress ()}, C.PTR_SIZEOF); | |
2117 AddRef (); | |
2118 return XPCOM.NS_OK; | |
2119 } | |
2120 if (guid.Equals (nsISupportsWeakReference.NS_ISUPPORTSWEAKREFERENCE_IID)) { | |
2121 XPCOM.memmove (ppvObject, new int /*long*/[] {supportsWeakReference.getAddress ()}, C.PTR_SIZEOF); | |
2122 AddRef (); | |
2123 return XPCOM.NS_OK; | |
2124 } | |
2125 if (guid.Equals (nsIContextMenuListener.NS_ICONTEXTMENULISTENER_IID)) { | |
2126 XPCOM.memmove (ppvObject, new int /*long*/[] {contextMenuListener.getAddress ()}, C.PTR_SIZEOF); | |
2127 AddRef (); | |
2128 return XPCOM.NS_OK; | |
2129 } | |
2130 if (guid.Equals (nsIURIContentListener.NS_IURICONTENTLISTENER_IID)) { | |
2131 XPCOM.memmove (ppvObject, new int /*long*/[] {uriContentListener.getAddress ()}, C.PTR_SIZEOF); | |
2132 AddRef (); | |
2133 return XPCOM.NS_OK; | |
2134 } | |
2135 if (guid.Equals (nsITooltipListener.NS_ITOOLTIPLISTENER_IID)) { | |
2136 XPCOM.memmove (ppvObject, new int /*long*/[] {tooltipListener.getAddress ()}, C.PTR_SIZEOF); | |
2137 AddRef (); | |
2138 return XPCOM.NS_OK; | |
2139 } | |
2140 XPCOM.memmove (ppvObject, new int /*long*/[] {0}, C.PTR_SIZEOF); | |
2141 return XPCOM.NS_ERROR_NO_INTERFACE; | |
2142 } | |
2143 | |
2144 int AddRef () { | |
2145 refCount++; | |
2146 return refCount; | |
2147 } | |
2148 | |
2149 int Release () { | |
2150 refCount--; | |
2151 if (refCount is 0) disposeCOMInterfaces (); | |
2152 return refCount; | |
2153 } | |
2154 | |
2155 /* nsIWeakReference */ | |
2156 | |
2157 int QueryReferent (int /*long*/ riid, int /*long*/ ppvObject) { | |
2158 return QueryInterface (riid, ppvObject); | |
2159 } | |
2160 | |
2161 /* nsIInterfaceRequestor */ | |
2162 | |
2163 int GetInterface (int /*long*/ riid, int /*long*/ ppvObject) { | |
2164 if (riid is 0 || ppvObject is 0) return XPCOM.NS_ERROR_NO_INTERFACE; | |
2165 nsID guid = new nsID (); | |
2166 XPCOM.memmove (guid, riid, nsID.sizeof); | |
2167 if (guid.Equals (nsIDOMWindow.NS_IDOMWINDOW_IID)) { | |
2168 int /*long*/[] aContentDOMWindow = new int /*long*/[1]; | |
2169 int rc = webBrowser.GetContentDOMWindow (aContentDOMWindow); | |
2170 if (rc !is XPCOM.NS_OK) error (rc); | |
2171 if (aContentDOMWindow[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2172 XPCOM.memmove (ppvObject, aContentDOMWindow, C.PTR_SIZEOF); | |
2173 return rc; | |
2174 } | |
2175 return QueryInterface (riid, ppvObject); | |
2176 } | |
2177 | |
2178 int GetWeakReference (int /*long*/ ppvObject) { | |
2179 XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF); | |
2180 AddRef (); | |
2181 return XPCOM.NS_OK; | |
2182 } | |
2183 | |
2184 /* nsIWebProgressListener */ | |
2185 | |
2186 int OnStateChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStateFlags, int aStatus) { | |
2187 if ((aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) is 0) return XPCOM.NS_OK; | |
2188 if ((aStateFlags & nsIWebProgressListener.STATE_START) !is 0) { | |
2189 if (request is 0) request = aRequest; | |
2190 | |
2191 if (!awaitingNavigate) { | |
2192 /* | |
2193 * Add the page's nsIDOMWindow to the collection of windows that will | |
2194 * have DOM listeners added to them later on in the page loading | |
2195 * process. These listeners cannot be added yet because the | |
2196 * nsIDOMWindow is not ready to take them at this stage. | |
2197 */ | |
2198 int /*long*/[] result = new int /*long*/[1]; | |
2199 nsIWebProgress progress = new nsIWebProgress (aWebProgress); | |
2200 int rc = progress.GetDOMWindow (result); | |
2201 if (rc !is XPCOM.NS_OK) error (rc); | |
2202 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2203 unhookedDOMWindows.addElement (new LONG (result[0])); | |
2204 } | |
2205 } else if ((aStateFlags & nsIWebProgressListener.STATE_REDIRECTING) !is 0) { | |
2206 if (request is aRequest) request = 0; | |
2207 } else if ((aStateFlags & nsIWebProgressListener.STATE_STOP) !is 0) { | |
2208 /* | |
2209 * If this page's nsIDOMWindow handle is still in unhookedDOMWindows then | |
2210 * add its DOM listeners now. It's possible for this to happen since | |
2211 * there is no guarantee that a STATE_TRANSFERRING state change will be | |
2212 * received for every window in a page, which is when these listeners | |
2213 * are typically added. | |
2214 */ | |
2215 int /*long*/[] result = new int /*long*/[1]; | |
2216 nsIWebProgress progress = new nsIWebProgress (aWebProgress); | |
2217 int rc = progress.GetDOMWindow (result); | |
2218 if (rc !is XPCOM.NS_OK) error (rc); | |
2219 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2220 nsIDOMWindow domWindow = new nsIDOMWindow (result[0]); | |
2221 | |
2222 LONG ptrObject = new LONG (result[0]); | |
2223 result[0] = 0; | |
2224 int index = unhookedDOMWindows.indexOf (ptrObject); | |
2225 if (index !is -1) { | |
2226 rc = webBrowser.GetContentDOMWindow (result); | |
2227 if (rc !is XPCOM.NS_OK) error (rc); | |
2228 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2229 bool isTop = result[0] is domWindow.getAddress (); | |
2230 new nsISupports (result[0]).Release (); | |
2231 result[0] = 0; | |
2232 | |
2233 rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result); | |
2234 if (rc !is XPCOM.NS_OK) error (rc); | |
2235 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2236 | |
2237 nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); | |
2238 result[0] = 0; | |
2239 hookDOMListeners (target, isTop); | |
2240 target.Release (); | |
2241 | |
2242 /* | |
2243 * Remove and unreference the nsIDOMWindow from the collection of windows | |
2244 * that are waiting to have DOM listeners hooked on them. | |
2245 */ | |
2246 unhookedDOMWindows.remove (ptrObject); | |
2247 new nsISupports (ptrObject.value).Release (); | |
2248 } | |
2249 domWindow.Release (); | |
2250 | |
2251 /* | |
2252 * Feature in Mozilla. When a request is redirected (STATE_REDIRECTING), | |
2253 * it never reaches the state STATE_STOP and it is replaced with a new request. | |
2254 * The new request is received when it is in the state STATE_STOP. | |
2255 * To handle this case, the variable request is set to 0 when the corresponding | |
2256 * request is redirected. The following request received with the state STATE_STOP | |
2257 * - the new request resulting from the redirection - is used to send | |
2258 * the ProgressListener.completed event. | |
2259 */ | |
2260 if (request is aRequest || request is 0) { | |
2261 request = 0; | |
2262 if (!awaitingNavigate) { | |
2263 StatusTextEvent event = new StatusTextEvent (browser); | |
2264 event.display = browser.getDisplay (); | |
2265 event.widget = browser; | |
2266 event.text = ""; //$NON-NLS-1$ | |
2267 for (int i = 0; i < statusTextListeners.length; i++) { | |
2268 statusTextListeners[i].changed (event); | |
2269 } | |
2270 ProgressEvent event2 = new ProgressEvent (browser); | |
2271 event2.display = browser.getDisplay (); | |
2272 event2.widget = browser; | |
2273 for (int i = 0; i < progressListeners.length; i++) { | |
2274 progressListeners[i].completed (event2); | |
2275 } | |
2276 } | |
2277 } | |
2278 } else if ((aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING) !is 0) { | |
2279 /* | |
2280 * Hook DOM listeners to the page's nsIDOMWindow here because this is | |
2281 * the earliest opportunity to do so. | |
2282 */ | |
2283 int /*long*/[] result = new int /*long*/[1]; | |
2284 nsIWebProgress progress = new nsIWebProgress (aWebProgress); | |
2285 int rc = progress.GetDOMWindow (result); | |
2286 if (rc !is XPCOM.NS_OK) error (rc); | |
2287 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2288 nsIDOMWindow domWindow = new nsIDOMWindow (result[0]); | |
2289 | |
2290 LONG ptrObject = new LONG (result[0]); | |
2291 result[0] = 0; | |
2292 int index = unhookedDOMWindows.indexOf (ptrObject); | |
2293 if (index !is -1) { | |
2294 rc = webBrowser.GetContentDOMWindow (result); | |
2295 if (rc !is XPCOM.NS_OK) error (rc); | |
2296 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2297 bool isTop = result[0] is domWindow.getAddress (); | |
2298 new nsISupports (result[0]).Release (); | |
2299 result[0] = 0; | |
2300 | |
2301 rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result); | |
2302 if (rc !is XPCOM.NS_OK) error (rc); | |
2303 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2304 | |
2305 nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); | |
2306 result[0] = 0; | |
2307 hookDOMListeners (target, isTop); | |
2308 target.Release (); | |
2309 | |
2310 /* | |
2311 * Remove and unreference the nsIDOMWindow from the collection of windows | |
2312 * that are waiting to have DOM listeners hooked on them. | |
2313 */ | |
2314 unhookedDOMWindows.remove (ptrObject); | |
2315 new nsISupports (ptrObject.value).Release (); | |
2316 } | |
2317 domWindow.Release (); | |
2318 } | |
2319 return XPCOM.NS_OK; | |
2320 } | |
2321 | |
2322 int OnProgressChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aCurSelfProgress, int aMaxSelfProgress, int aCurTotalProgress, int aMaxTotalProgress) { | |
2323 if (awaitingNavigate || progressListeners.length is 0) return XPCOM.NS_OK; | |
2324 ProgressEvent event = new ProgressEvent (browser); | |
2325 event.display = browser.getDisplay (); | |
2326 event.widget = browser; | |
2327 event.current = aCurTotalProgress; | |
2328 event.total = aMaxTotalProgress; | |
2329 for (int i = 0; i < progressListeners.length; i++) { | |
2330 progressListeners[i].changed (event); | |
2331 } | |
2332 return XPCOM.NS_OK; | |
2333 } | |
2334 | |
2335 int OnLocationChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aLocation) { | |
2336 /* | |
2337 * Feature in Mozilla. When a page is loaded via setText before a previous | |
2338 * setText page load has completed, the expected OnStateChange STATE_STOP for the | |
2339 * original setText never arrives because it gets replaced by the OnStateChange | |
2340 * STATE_STOP for the new request. This results in the request field never being | |
2341 * cleared because the original request's OnStateChange STATE_STOP is still expected | |
2342 * (but never arrives). To handle this case, the request field is updated to the new | |
2343 * overriding request since its OnStateChange STATE_STOP will be received next. | |
2344 */ | |
2345 if (request !is 0 && request !is aRequest) request = aRequest; | |
2346 | |
2347 if (awaitingNavigate || locationListeners.length is 0) return XPCOM.NS_OK; | |
2348 | |
2349 nsIWebProgress webProgress = new nsIWebProgress (aWebProgress); | |
2350 int /*long*/[] aDOMWindow = new int /*long*/[1]; | |
2351 int rc = webProgress.GetDOMWindow (aDOMWindow); | |
2352 if (rc !is XPCOM.NS_OK) error (rc); | |
2353 if (aDOMWindow[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2354 | |
2355 nsIDOMWindow domWindow = new nsIDOMWindow (aDOMWindow[0]); | |
2356 int /*long*/[] aTop = new int /*long*/[1]; | |
2357 rc = domWindow.GetTop (aTop); | |
2358 if (rc !is XPCOM.NS_OK) error (rc); | |
2359 if (aTop[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2360 domWindow.Release (); | |
2361 | |
2362 nsIDOMWindow topWindow = new nsIDOMWindow (aTop[0]); | |
2363 topWindow.Release (); | |
2364 | |
2365 nsIURI location = new nsIURI (aLocation); | |
2366 int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); | |
2367 location.GetSpec (aSpec); | |
2368 int length = XPCOM.nsEmbedCString_Length (aSpec); | |
2369 int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec); | |
2370 byte[] dest = new byte[length]; | |
2371 XPCOM.memmove (dest, buffer, length); | |
2372 XPCOM.nsEmbedCString_delete (aSpec); | |
2373 String url = new String (dest); | |
2374 | |
2375 /* | |
2376 * As of Mozilla 1.8, the first time that a page is displayed, regardless of | |
2377 * whether it's via Browser.setURL() or Browser.setText(), the GRE navigates | |
2378 * to about:blank and fires the corresponding navigation events. Do not send | |
2379 * this event on to the user since it is not expected. | |
2380 */ | |
2381 if (!IsPre_1_8 && aRequest is 0 && url.startsWith (ABOUT_BLANK)) return XPCOM.NS_OK; | |
2382 | |
2383 LocationEvent event = new LocationEvent (browser); | |
2384 event.display = browser.getDisplay (); | |
2385 event.widget = browser; | |
2386 event.location = url; | |
2387 /* | |
2388 * If the URI indicates that the page is being rendered from memory | |
2389 * (via setText()) then set it to about:blank to be consistent with IE. | |
2390 */ | |
2391 if (event.location.equals (URI_FROMMEMORY)) event.location = ABOUT_BLANK; | |
2392 event.top = aTop[0] is aDOMWindow[0]; | |
2393 for (int i = 0; i < locationListeners.length; i++) { | |
2394 locationListeners[i].changed (event); | |
2395 } | |
2396 return XPCOM.NS_OK; | |
2397 } | |
2398 | |
2399 int OnStatusChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStatus, int /*long*/ aMessage) { | |
2400 if (awaitingNavigate || statusTextListeners.length is 0) return XPCOM.NS_OK; | |
2401 StatusTextEvent event = new StatusTextEvent (browser); | |
2402 event.display = browser.getDisplay (); | |
2403 event.widget = browser; | |
2404 int length = XPCOM.strlen_PRUnichar (aMessage); | |
2405 char[] dest = new char[length]; | |
2406 XPCOM.memmove (dest, aMessage, length * 2); | |
2407 event.text = new String (dest); | |
2408 for (int i = 0; i < statusTextListeners.length; i++) { | |
2409 statusTextListeners[i].changed (event); | |
2410 } | |
2411 return XPCOM.NS_OK; | |
2412 } | |
2413 | |
2414 int OnSecurityChange (int /*long*/ aWebProgress, int /*long*/ aRequest, int state) { | |
2415 return XPCOM.NS_OK; | |
2416 } | |
2417 | |
2418 /* nsIWebBrowserChrome */ | |
2419 | |
2420 int SetStatus (int statusType, int /*long*/ status) { | |
2421 if (awaitingNavigate || statusTextListeners.length is 0) return XPCOM.NS_OK; | |
2422 StatusTextEvent event = new StatusTextEvent (browser); | |
2423 event.display = browser.getDisplay (); | |
2424 event.widget = browser; | |
2425 int length = XPCOM.strlen_PRUnichar (status); | |
2426 char[] dest = new char[length]; | |
2427 XPCOM.memmove (dest, status, length * 2); | |
2428 String string = new String (dest); | |
2429 event.text = string; | |
2430 for (int i = 0; i < statusTextListeners.length; i++) { | |
2431 statusTextListeners[i].changed (event); | |
2432 } | |
2433 return XPCOM.NS_OK; | |
2434 } | |
2435 | |
2436 int GetWebBrowser (int /*long*/ aWebBrowser) { | |
2437 int /*long*/[] ret = new int /*long*/[1]; | |
2438 if (webBrowser !is null) { | |
2439 webBrowser.AddRef (); | |
2440 ret[0] = webBrowser.getAddress (); | |
2441 } | |
2442 XPCOM.memmove (aWebBrowser, ret, C.PTR_SIZEOF); | |
2443 return XPCOM.NS_OK; | |
2444 } | |
2445 | |
2446 int SetWebBrowser (int /*long*/ aWebBrowser) { | |
2447 if (webBrowser !is null) webBrowser.Release (); | |
2448 webBrowser = aWebBrowser !is 0 ? new nsIWebBrowser (aWebBrowser) : null; | |
2449 return XPCOM.NS_OK; | |
2450 } | |
2451 | |
2452 int GetChromeFlags (int /*long*/ aChromeFlags) { | |
2453 int[] ret = new int[1]; | |
2454 ret[0] = chromeFlags; | |
2455 XPCOM.memmove (aChromeFlags, ret, 4); /* PRUint32 */ | |
2456 return XPCOM.NS_OK; | |
2457 } | |
2458 | |
2459 int SetChromeFlags (int aChromeFlags) { | |
2460 chromeFlags = aChromeFlags; | |
2461 return XPCOM.NS_OK; | |
2462 } | |
2463 | |
2464 int DestroyBrowserWindow () { | |
2465 WindowEvent newEvent = new WindowEvent (browser); | |
2466 newEvent.display = browser.getDisplay (); | |
2467 newEvent.widget = browser; | |
2468 for (int i = 0; i < closeWindowListeners.length; i++) { | |
2469 closeWindowListeners[i].close (newEvent); | |
2470 } | |
2471 /* | |
2472 * Note on Mozilla. The DestroyBrowserWindow notification cannot be cancelled. | |
2473 * The browser widget cannot be used after this notification has been received. | |
2474 * The application is advised to close the window hosting the browser widget. | |
2475 * The browser widget must be disposed in all cases. | |
2476 */ | |
2477 browser.dispose (); | |
2478 return XPCOM.NS_OK; | |
2479 } | |
2480 | |
2481 int SizeBrowserTo (int aCX, int aCY) { | |
2482 size = new Point (aCX, aCY); | |
2483 bool isChrome = (chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) !is 0; | |
2484 if (isChrome) { | |
2485 Shell shell = browser.getShell (); | |
2486 shell.setSize (shell.computeSize (size.x, size.y)); | |
2487 } | |
2488 return XPCOM.NS_OK; | |
2489 } | |
2490 | |
2491 int ShowAsModal () { | |
2492 int /*long*/[] result = new int /*long*/[1]; | |
2493 int rc = XPCOM.NS_GetServiceManager (result); | |
2494 if (rc !is XPCOM.NS_OK) error (rc); | |
2495 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2496 | |
2497 nsIServiceManager serviceManager = new nsIServiceManager (result[0]); | |
2498 result[0] = 0; | |
2499 byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_CONTEXTSTACK_CONTRACTID, true); | |
2500 rc = serviceManager.GetServiceByContractID (aContractID, nsIJSContextStack.NS_IJSCONTEXTSTACK_IID, result); | |
2501 if (rc !is XPCOM.NS_OK) error (rc); | |
2502 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2503 serviceManager.Release (); | |
2504 | |
2505 nsIJSContextStack stack = new nsIJSContextStack (result[0]); | |
2506 result[0] = 0; | |
2507 rc = stack.Push (0); | |
2508 if (rc !is XPCOM.NS_OK) error (rc); | |
2509 | |
2510 Shell shell = browser.getShell (); | |
2511 Display display = browser.getDisplay (); | |
2512 while (!shell.isDisposed ()) { | |
2513 if (!display.readAndDispatch ()) display.sleep (); | |
2514 } | |
2515 | |
2516 rc = stack.Pop (result); | |
2517 if (rc !is XPCOM.NS_OK) error (rc); | |
2518 stack.Release (); | |
2519 return XPCOM.NS_OK; | |
2520 } | |
2521 | |
2522 int IsWindowModal (int /*long*/ retval) { | |
2523 int result = (chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) !is 0 ? 1 : 0; | |
2524 XPCOM.memmove (retval, new int[] {result}, 4); /* PRBool */ | |
2525 return XPCOM.NS_OK; | |
2526 } | |
2527 | |
2528 int ExitModalEventLoop (int aStatus) { | |
2529 return XPCOM.NS_OK; | |
2530 } | |
2531 | |
2532 /* nsIEmbeddingSiteWindow */ | |
2533 | |
2534 int SetDimensions (int flags, int x, int y, int cx, int cy) { | |
2535 if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) !is 0) { | |
2536 location = new Point (x, y); | |
2537 browser.getShell ().setLocation (x, y); | |
2538 } | |
2539 if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_INNER) !is 0) { | |
2540 browser.setSize (cx, cy); | |
2541 } | |
2542 if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_OUTER) !is 0) { | |
2543 browser.getShell ().setSize (cx, cy); | |
2544 } | |
2545 return XPCOM.NS_OK; | |
2546 } | |
2547 | |
2548 int GetDimensions (int flags, int /*long*/ x, int /*long*/ y, int /*long*/ cx, int /*long*/ cy) { | |
2549 if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) !is 0) { | |
2550 Point location = browser.getShell ().getLocation (); | |
2551 if (x !is 0) C.memmove (x, new int[] {location.x}, 4); /* PRInt32 */ | |
2552 if (y !is 0) C.memmove (y, new int[] {location.y}, 4); /* PRInt32 */ | |
2553 } | |
2554 if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_INNER) !is 0) { | |
2555 Point size = browser.getSize (); | |
2556 if (cx !is 0) C.memmove (cx, new int[] {size.x}, 4); /* PRInt32 */ | |
2557 if (cy !is 0) C.memmove (cy, new int[] {size.y}, 4); /* PRInt32 */ | |
2558 } | |
2559 if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_OUTER) !is 0) { | |
2560 Point size = browser.getShell().getSize (); | |
2561 if (cx !is 0) C.memmove (cx, new int[] {size.x}, 4); /* PRInt32 */ | |
2562 if (cy !is 0) C.memmove (cy, new int[] {size.y}, 4); /* PRInt32 */ | |
2563 } | |
2564 return XPCOM.NS_OK; | |
2565 } | |
2566 | |
2567 int SetFocus () { | |
2568 int /*long*/[] result = new int /*long*/[1]; | |
2569 int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); | |
2570 if (rc !is XPCOM.NS_OK) error (rc); | |
2571 if (result[0] is 0) error (XPCOM.NS_ERROR_NO_INTERFACE); | |
2572 | |
2573 nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); | |
2574 rc = baseWindow.SetFocus (); | |
2575 if (rc !is XPCOM.NS_OK) error (rc); | |
2576 baseWindow.Release (); | |
2577 | |
2578 /* | |
2579 * Note. Mozilla notifies here that one of the children took | |
2580 * focus. This could or should be used to fire an DWT.FOCUS_IN | |
2581 * event on Browser focus listeners. | |
2582 */ | |
2583 return XPCOM.NS_OK; | |
2584 } | |
2585 | |
2586 int GetVisibility (int /*long*/ aVisibility) { | |
2587 bool visible = browser.isVisible () && !browser.getShell ().getMinimized (); | |
2588 XPCOM.memmove (aVisibility, new int[] {visible ? 1 : 0}, 4); /* PRBool */ | |
2589 return XPCOM.NS_OK; | |
2590 } | |
2591 | |
2592 int SetVisibility (int aVisibility) { | |
2593 if (isChild) { | |
2594 WindowEvent event = new WindowEvent (browser); | |
2595 event.display = browser.getDisplay (); | |
2596 event.widget = browser; | |
2597 if (aVisibility !is 0) { | |
2598 /* | |
2599 * Bug in Mozilla. When the JavaScript window.open is executed, Mozilla | |
2600 * fires multiple SetVisibility 1 notifications. The workaround is | |
2601 * to ignore subsequent notifications. | |
2602 */ | |
2603 if (!visible) { | |
2604 visible = true; | |
2605 event.location = location; | |
2606 event.size = size; | |
2607 event.addressBar = (chromeFlags & nsIWebBrowserChrome.CHROME_LOCATIONBAR) !is 0; | |
2608 event.menuBar = (chromeFlags & nsIWebBrowserChrome.CHROME_MENUBAR) !is 0; | |
2609 event.statusBar = (chromeFlags & nsIWebBrowserChrome.CHROME_STATUSBAR) !is 0; | |
2610 event.toolBar = (chromeFlags & nsIWebBrowserChrome.CHROME_TOOLBAR) !is 0; | |
2611 for (int i = 0; i < visibilityWindowListeners.length; i++) { | |
2612 visibilityWindowListeners[i].show (event); | |
2613 } | |
2614 location = null; | |
2615 size = null; | |
2616 } | |
2617 } else { | |
2618 visible = false; | |
2619 for (int i = 0; i < visibilityWindowListeners.length; i++) { | |
2620 visibilityWindowListeners[i].hide (event); | |
2621 } | |
2622 } | |
2623 } else { | |
2624 visible = aVisibility !is 0; | |
2625 } | |
2626 return XPCOM.NS_OK; | |
2627 } | |
2628 | |
2629 int GetTitle (int /*long*/ aTitle) { | |
2630 return XPCOM.NS_OK; | |
2631 } | |
2632 | |
2633 int SetTitle (int /*long*/ aTitle) { | |
2634 if (awaitingNavigate || titleListeners.length is 0) return XPCOM.NS_OK; | |
2635 TitleEvent event = new TitleEvent (browser); | |
2636 event.display = browser.getDisplay (); | |
2637 event.widget = browser; | |
2638 /* | |
2639 * To be consistent with other platforms the title event should | |
2640 * contain the page's url if the page does not contain a <title> | |
2641 * tag. | |
2642 */ | |
2643 int length = XPCOM.strlen_PRUnichar (aTitle); | |
2644 if (length > 0) { | |
2645 char[] dest = new char[length]; | |
2646 XPCOM.memmove (dest, aTitle, length * 2); | |
2647 event.title = new String (dest); | |
2648 } else { | |
2649 event.title = getUrl (); | |
2650 } | |
2651 for (int i = 0; i < titleListeners.length; i++) { | |
2652 titleListeners[i].changed (event); | |
2653 } | |
2654 return XPCOM.NS_OK; | |
2655 } | |
2656 | |
2657 int GetSiteWindow (int /*long*/ aSiteWindow) { | |
2658 /* | |
2659 * Note. The handle is expected to be an HWND on Windows and | |
2660 * a GtkWidget* on GTK. This callback is invoked on Windows | |
2661 * when the javascript window.print is invoked and the print | |
2662 * dialog comes up. If no handle is returned, the print dialog | |
2663 * does not come up on this platform. | |
2664 */ | |
2665 XPCOM.memmove (aSiteWindow, new int /*long*/[] {embedHandle}, C.PTR_SIZEOF); | |
2666 return XPCOM.NS_OK; | |
2667 } | |
2668 | |
2669 /* nsIWebBrowserChromeFocus */ | |
2670 | |
2671 int FocusNextElement () { | |
2672 /* | |
2673 * Bug in Mozilla embedding API. Mozilla takes back the focus after sending | |
2674 * this event. This prevents tabbing out of Mozilla. This behaviour can be reproduced | |
2675 * with the Mozilla application TestGtkEmbed. The workaround is to | |
2676 * send the traversal notification after this callback returns. | |
2677 */ | |
2678 browser.getDisplay ().asyncExec (new Runnable () { | |
2679 public void run () { | |
2680 if (browser.isDisposed ()) return; | |
2681 browser.traverse (DWT.TRAVERSE_TAB_NEXT); | |
2682 } | |
2683 }); | |
2684 return XPCOM.NS_OK; | |
2685 } | |
2686 | |
2687 int FocusPrevElement () { | |
2688 /* | |
2689 * Bug in Mozilla embedding API. Mozilla takes back the focus after sending | |
2690 * this event. This prevents tabbing out of Mozilla. This behaviour can be reproduced | |
2691 * with the Mozilla application TestGtkEmbed. The workaround is to | |
2692 * send the traversal notification after this callback returns. | |
2693 */ | |
2694 browser.getDisplay ().asyncExec (new Runnable () { | |
2695 public void run () { | |
2696 if (browser.isDisposed ()) return; | |
2697 browser.traverse (DWT.TRAVERSE_TAB_PREVIOUS); | |
2698 } | |
2699 }); | |
2700 return XPCOM.NS_OK; | |
2701 } | |
2702 | |
2703 /* nsIContextMenuListener */ | |
2704 | |
2705 int OnShowContextMenu (int aContextFlags, int /*long*/ aEvent, int /*long*/ aNode) { | |
2706 if (awaitingNavigate) return XPCOM.NS_OK; | |
2707 | |
2708 nsIDOMEvent domEvent = new nsIDOMEvent (aEvent); | |
2709 int /*long*/[] result = new int /*long*/[1]; | |
2710 int rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result); | |
2711 if (rc !is XPCOM.NS_OK) error (rc); | |
2712 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2713 | |
2714 nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]); | |
2715 int[] aScreenX = new int[1], aScreenY = new int[1]; | |
2716 rc = domMouseEvent.GetScreenX (aScreenX); | |
2717 if (rc !is XPCOM.NS_OK) error (rc); | |
2718 rc = domMouseEvent.GetScreenY (aScreenY); | |
2719 if (rc !is XPCOM.NS_OK) error (rc); | |
2720 domMouseEvent.Release (); | |
2721 | |
2722 Event event = new Event (); | |
2723 event.x = aScreenX[0]; | |
2724 event.y = aScreenY[0]; | |
2725 browser.notifyListeners (DWT.MenuDetect, event); | |
2726 if (!event.doit || browser.isDisposed ()) return XPCOM.NS_OK; | |
2727 Menu menu = browser.getMenu (); | |
2728 if (menu !is null && !menu.isDisposed ()) { | |
2729 if (aScreenX[0] !is event.x || aScreenY[0] !is event.y) { | |
2730 menu.setLocation (event.x, event.y); | |
2731 } | |
2732 menu.setVisible (true); | |
2733 } | |
2734 return XPCOM.NS_OK; | |
2735 } | |
2736 | |
2737 /* nsIURIContentListener */ | |
2738 | |
2739 int OnStartURIOpen (int /*long*/ aURI, int /*long*/ retval) { | |
2740 if (awaitingNavigate || locationListeners.length is 0) { | |
2741 XPCOM.memmove (retval, new int[] {0}, 4); /* PRBool */ | |
2742 return XPCOM.NS_OK; | |
2743 } | |
2744 nsIURI location = new nsIURI (aURI); | |
2745 int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); | |
2746 location.GetSpec (aSpec); | |
2747 int length = XPCOM.nsEmbedCString_Length (aSpec); | |
2748 int /*long*/ buffer = XPCOM.nsEmbedCString_get (aSpec); | |
2749 buffer = XPCOM.nsEmbedCString_get (aSpec); | |
2750 byte[] dest = new byte[length]; | |
2751 XPCOM.memmove (dest, buffer, length); | |
2752 XPCOM.nsEmbedCString_delete (aSpec); | |
2753 String value = new String (dest); | |
2754 bool doit = true; | |
2755 if (request is 0) { | |
2756 /* | |
2757 * listeners should not be notified of internal transitions like "javascipt:..." | |
2758 * because this is an implementation side-effect, not a true navigate | |
2759 */ | |
2760 if (!value.startsWith (PREFIX_JAVASCRIPT)) { | |
2761 LocationEvent event = new LocationEvent (browser); | |
2762 event.display = browser.getDisplay(); | |
2763 event.widget = browser; | |
2764 event.location = value; | |
2765 /* | |
2766 * If the URI indicates that the page is being rendered from memory | |
2767 * (via setText()) then set it to about:blank to be consistent with IE. | |
2768 */ | |
2769 if (event.location.equals (URI_FROMMEMORY)) event.location = ABOUT_BLANK; | |
2770 event.doit = doit; | |
2771 for (int i = 0; i < locationListeners.length; i++) { | |
2772 locationListeners[i].changing (event); | |
2773 } | |
2774 doit = event.doit && !browser.isDisposed(); | |
2775 } | |
2776 } | |
2777 XPCOM.memmove (retval, new int[] {doit ? 0 : 1}, 4); /* PRBool */ | |
2778 return XPCOM.NS_OK; | |
2779 } | |
2780 | |
2781 int DoContent (int /*long*/ aContentType, int aIsContentPreferred, int /*long*/ aRequest, int /*long*/ aContentHandler, int /*long*/ retval) { | |
2782 return XPCOM.NS_ERROR_NOT_IMPLEMENTED; | |
2783 } | |
2784 | |
2785 int IsPreferred (int /*long*/ aContentType, int /*long*/ aDesiredContentType, int /*long*/ retval) { | |
2786 bool preferred = false; | |
2787 int size = XPCOM.strlen (aContentType); | |
2788 if (size > 0) { | |
2789 byte[] typeBytes = new byte[size + 1]; | |
2790 XPCOM.memmove (typeBytes, aContentType, size); | |
2791 String contentType = new String (typeBytes, 0, size); | |
2792 | |
2793 /* do not attempt to handle known problematic content types */ | |
2794 if (!contentType.equals (XPCOM.CONTENT_MAYBETEXT) && !contentType.equals (XPCOM.CONTENT_MULTIPART)) { | |
2795 /* determine whether browser can handle the content type */ | |
2796 int /*long*/[] result = new int /*long*/[1]; | |
2797 int rc = XPCOM.NS_GetServiceManager (result); | |
2798 if (rc !is XPCOM.NS_OK) error (rc); | |
2799 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2800 nsIServiceManager serviceManager = new nsIServiceManager (result[0]); | |
2801 result[0] = 0; | |
2802 | |
2803 /* First try to use the nsIWebNavigationInfo if it's available (>= mozilla 1.8) */ | |
2804 byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WEBNAVIGATIONINFO_CONTRACTID, true); | |
2805 rc = serviceManager.GetServiceByContractID (aContractID, nsIWebNavigationInfo.NS_IWEBNAVIGATIONINFO_IID, result); | |
2806 if (rc is 0) { | |
2807 byte[] bytes = MozillaDelegate.wcsToMbcs (null, contentType, true); | |
2808 int /*long*/ typePtr = XPCOM.nsEmbedCString_new (bytes, bytes.length); | |
2809 nsIWebNavigationInfo info = new nsIWebNavigationInfo (result[0]); | |
2810 result[0] = 0; | |
2811 int[] isSupportedResult = new int[1]; /* PRUint32 */ | |
2812 rc = info.IsTypeSupported (typePtr, 0, isSupportedResult); | |
2813 if (rc !is XPCOM.NS_OK) error (rc); | |
2814 info.Release (); | |
2815 XPCOM.nsEmbedCString_delete (typePtr); | |
2816 preferred = isSupportedResult[0] !is 0; | |
2817 } else { | |
2818 /* nsIWebNavigationInfo is not available, so do the type lookup */ | |
2819 result[0] = 0; | |
2820 rc = serviceManager.GetService (XPCOM.NS_CATEGORYMANAGER_CID, nsICategoryManager.NS_ICATEGORYMANAGER_IID, result); | |
2821 if (rc !is XPCOM.NS_OK) error (rc); | |
2822 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2823 | |
2824 nsICategoryManager categoryManager = new nsICategoryManager (result[0]); | |
2825 result[0] = 0; | |
2826 byte[] categoryBytes = MozillaDelegate.wcsToMbcs (null, "Gecko-Content-Viewers", true); //$NON-NLS-1$ | |
2827 rc = categoryManager.GetCategoryEntry (categoryBytes, typeBytes, result); | |
2828 categoryManager.Release (); | |
2829 /* if no viewer for the content type is registered then rc is XPCOM.NS_ERROR_NOT_AVAILABLE */ | |
2830 preferred = rc is XPCOM.NS_OK; | |
2831 } | |
2832 serviceManager.Release (); | |
2833 } | |
2834 } | |
2835 | |
2836 XPCOM.memmove(retval, new int[] {preferred ? 1 : 0}, 4); /* PRBool */ | |
2837 if (preferred) { | |
2838 XPCOM.memmove (aDesiredContentType, new int /*long*/[] {0}, C.PTR_SIZEOF); | |
2839 } | |
2840 return XPCOM.NS_OK; | |
2841 } | |
2842 | |
2843 int CanHandleContent (int /*long*/ aContentType, int aIsContentPreferred, int /*long*/ aDesiredContentType, int /*long*/ retval) { | |
2844 return XPCOM.NS_ERROR_NOT_IMPLEMENTED; | |
2845 } | |
2846 | |
2847 int GetLoadCookie (int /*long*/ aLoadCookie) { | |
2848 return XPCOM.NS_ERROR_NOT_IMPLEMENTED; | |
2849 } | |
2850 | |
2851 int SetLoadCookie (int /*long*/ aLoadCookie) { | |
2852 return XPCOM.NS_ERROR_NOT_IMPLEMENTED; | |
2853 } | |
2854 | |
2855 int GetParentContentListener (int /*long*/ aParentContentListener) { | |
2856 return XPCOM.NS_ERROR_NOT_IMPLEMENTED; | |
2857 } | |
2858 | |
2859 int SetParentContentListener (int /*long*/ aParentContentListener) { | |
2860 return XPCOM.NS_ERROR_NOT_IMPLEMENTED; | |
2861 } | |
2862 | |
2863 /* nsITooltipListener */ | |
2864 | |
2865 int OnShowTooltip (int aXCoords, int aYCoords, int /*long*/ aTipText) { | |
2866 if (awaitingNavigate) return XPCOM.NS_OK; | |
2867 | |
2868 int length = XPCOM.strlen_PRUnichar (aTipText); | |
2869 char[] dest = new char[length]; | |
2870 XPCOM.memmove (dest, aTipText, length * 2); | |
2871 String text = new String (dest); | |
2872 if (tip !is null && !tip.isDisposed ()) tip.dispose (); | |
2873 Display display = browser.getDisplay (); | |
2874 Shell parent = browser.getShell (); | |
2875 tip = new Shell (parent, DWT.ON_TOP); | |
2876 tip.setLayout (new FillLayout()); | |
2877 Label label = new Label (tip, DWT.CENTER); | |
2878 label.setForeground (display.getSystemColor (DWT.COLOR_INFO_FOREGROUND)); | |
2879 label.setBackground (display.getSystemColor (DWT.COLOR_INFO_BACKGROUND)); | |
2880 label.setText (text); | |
2881 /* | |
2882 * Bug in Mozilla embedded API. Tooltip coordinates are wrong for | |
2883 * elements inside an inline frame (IFrame tag). The workaround is | |
2884 * to position the tooltip based on the mouse cursor location. | |
2885 */ | |
2886 Point point = display.getCursorLocation (); | |
2887 /* Assuming cursor is 21x21 because this is the size of | |
2888 * the arrow cursor on Windows | |
2889 */ | |
2890 point.y += 21; | |
2891 tip.setLocation (point); | |
2892 tip.pack (); | |
2893 tip.setVisible (true); | |
2894 return XPCOM.NS_OK; | |
2895 } | |
2896 | |
2897 int OnHideTooltip () { | |
2898 if (tip !is null && !tip.isDisposed ()) tip.dispose (); | |
2899 tip = null; | |
2900 return XPCOM.NS_OK; | |
2901 } | |
2902 | |
2903 /* nsIDOMEventListener */ | |
2904 | |
2905 int HandleEvent (int /*long*/ event) { | |
2906 nsIDOMEvent domEvent = new nsIDOMEvent (event); | |
2907 | |
2908 int /*long*/ type = XPCOM.nsEmbedString_new (); | |
2909 int rc = domEvent.GetType (type); | |
2910 if (rc !is XPCOM.NS_OK) error (rc); | |
2911 int length = XPCOM.nsEmbedString_Length (type); | |
2912 int /*long*/ buffer = XPCOM.nsEmbedString_get (type); | |
2913 char[] chars = new char[length]; | |
2914 XPCOM.memmove (chars, buffer, length * 2); | |
2915 String typeString = new String (chars); | |
2916 XPCOM.nsEmbedString_delete (type); | |
2917 | |
2918 if (XPCOM.DOMEVENT_UNLOAD.equals (typeString)) { | |
2919 int /*long*/[] result = new int /*long*/[1]; | |
2920 rc = domEvent.GetCurrentTarget (result); | |
2921 if (rc !is XPCOM.NS_OK) error (rc); | |
2922 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2923 | |
2924 nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); | |
2925 unhookDOMListeners (target); | |
2926 target.Release (); | |
2927 return XPCOM.NS_OK; | |
2928 } | |
2929 | |
2930 if (XPCOM.DOMEVENT_FOCUS.equals (typeString)) { | |
2931 delegate.handleFocus (); | |
2932 return XPCOM.NS_OK; | |
2933 } | |
2934 | |
2935 if (XPCOM.DOMEVENT_KEYDOWN.equals (typeString)) { | |
2936 int /*long*/[] result = new int /*long*/[1]; | |
2937 rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID, result); | |
2938 if (rc !is XPCOM.NS_OK) error (rc); | |
2939 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
2940 nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]); | |
2941 result[0] = 0; | |
2942 | |
2943 int[] aKeyCode = new int[1]; /* PRUint32 */ | |
2944 rc = domKeyEvent.GetKeyCode (aKeyCode); | |
2945 if (rc !is XPCOM.NS_OK) error (rc); | |
2946 int keyCode = translateKey (aKeyCode[0]); | |
2947 | |
2948 /* | |
2949 * if keyCode is lastKeyCode then either a repeating key like Shift | |
2950 * is being held or a key for which key events are not sent has been | |
2951 * pressed. In both of these cases a KeyDown should not be sent. | |
2952 */ | |
2953 if (keyCode !is lastKeyCode) { | |
2954 lastKeyCode = keyCode; | |
2955 switch (keyCode) { | |
2956 case DWT.SHIFT: | |
2957 case DWT.CONTROL: | |
2958 case DWT.ALT: | |
2959 case DWT.CAPS_LOCK: | |
2960 case DWT.NUM_LOCK: | |
2961 case DWT.SCROLL_LOCK: | |
2962 case DWT.COMMAND: { | |
2963 /* keypress events will not be received for these keys, so send KeyDowns for them now */ | |
2964 int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ | |
2965 rc = domKeyEvent.GetAltKey (aAltKey); | |
2966 if (rc !is XPCOM.NS_OK) error (rc); | |
2967 rc = domKeyEvent.GetCtrlKey (aCtrlKey); | |
2968 if (rc !is XPCOM.NS_OK) error (rc); | |
2969 rc = domKeyEvent.GetShiftKey (aShiftKey); | |
2970 if (rc !is XPCOM.NS_OK) error (rc); | |
2971 rc = domKeyEvent.GetMetaKey (aMetaKey); | |
2972 if (rc !is XPCOM.NS_OK) error (rc); | |
2973 | |
2974 Event keyEvent = new Event (); | |
2975 keyEvent.widget = browser; | |
2976 keyEvent.type = DWT.KeyDown; | |
2977 keyEvent.keyCode = keyCode; | |
2978 keyEvent.stateMask = (aAltKey[0] !is 0 ? DWT.ALT : 0) | (aCtrlKey[0] !is 0 ? DWT.CTRL : 0) | (aShiftKey[0] !is 0 ? DWT.SHIFT : 0) | (aMetaKey[0] !is 0 ? DWT.COMMAND : 0); | |
2979 keyEvent.stateMask &= ~keyCode; /* remove current keydown if it's a state key */ | |
2980 browser.notifyListeners (keyEvent.type, keyEvent); | |
2981 if (!keyEvent.doit || browser.isDisposed ()) { | |
2982 domEvent.PreventDefault (); | |
2983 } | |
2984 break; | |
2985 } | |
2986 default: { | |
2987 /* | |
2988 * If the keydown has Meta (but not Meta+Ctrl) as a modifier then send a KeyDown event for it here | |
2989 * because a corresponding keypress event will not be received for it from the DOM. If the keydown | |
2990 * does not have Meta as a modifier, or has Meta+Ctrl as a modifier, then then do nothing here | |
2991 * because its KeyDown event will be sent from the keypress listener. | |
2992 */ | |
2993 int[] aMetaKey = new int[1]; /* PRBool */ | |
2994 rc = domKeyEvent.GetMetaKey (aMetaKey); | |
2995 if (rc !is XPCOM.NS_OK) error (rc); | |
2996 if (aMetaKey[0] !is 0) { | |
2997 int[] aCtrlKey = new int[1]; /* PRBool */ | |
2998 rc = domKeyEvent.GetCtrlKey (aCtrlKey); | |
2999 if (rc !is XPCOM.NS_OK) error (rc); | |
3000 if (aCtrlKey[0] is 0) { | |
3001 int[] aAltKey = new int[1], aShiftKey = new int[1]; /* PRBool */ | |
3002 rc = domKeyEvent.GetAltKey (aAltKey); | |
3003 if (rc !is XPCOM.NS_OK) error (rc); | |
3004 rc = domKeyEvent.GetShiftKey (aShiftKey); | |
3005 if (rc !is XPCOM.NS_OK) error (rc); | |
3006 | |
3007 Event keyEvent = new Event (); | |
3008 keyEvent.widget = browser; | |
3009 keyEvent.type = DWT.KeyDown; | |
3010 keyEvent.keyCode = lastKeyCode; | |
3011 keyEvent.stateMask = (aAltKey[0] !is 0 ? DWT.ALT : 0) | (aCtrlKey[0] !is 0? DWT.CTRL : 0) | (aShiftKey[0] !is 0? DWT.SHIFT : 0) | (aMetaKey[0] !is 0? DWT.COMMAND : 0); | |
3012 browser.notifyListeners (keyEvent.type, keyEvent); | |
3013 if (!keyEvent.doit || browser.isDisposed ()) { | |
3014 domEvent.PreventDefault (); | |
3015 } | |
3016 } | |
3017 } | |
3018 } | |
3019 } | |
3020 } | |
3021 | |
3022 domKeyEvent.Release (); | |
3023 return XPCOM.NS_OK; | |
3024 } | |
3025 | |
3026 if (XPCOM.DOMEVENT_KEYPRESS.equals (typeString)) { | |
3027 /* | |
3028 * if keydown could not determine a keycode for this key then it's a | |
3029 * key for which key events are not sent (eg.- the Windows key) | |
3030 */ | |
3031 if (lastKeyCode is 0) return XPCOM.NS_OK; | |
3032 | |
3033 /* | |
3034 * On linux only, unexpected keypress events are received for some | |
3035 * modifier keys. The workaround is to ignore these events since | |
3036 * KeyDown events are sent for these keys in the keydown listener. | |
3037 */ | |
3038 switch (lastKeyCode) { | |
3039 case DWT.CAPS_LOCK: | |
3040 case DWT.NUM_LOCK: | |
3041 case DWT.SCROLL_LOCK: return XPCOM.NS_OK; | |
3042 } | |
3043 | |
3044 int /*long*/[] result = new int /*long*/[1]; | |
3045 rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID, result); | |
3046 if (rc !is XPCOM.NS_OK) error (rc); | |
3047 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
3048 nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]); | |
3049 result[0] = 0; | |
3050 | |
3051 int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ | |
3052 rc = domKeyEvent.GetAltKey (aAltKey); | |
3053 if (rc !is XPCOM.NS_OK) error (rc); | |
3054 rc = domKeyEvent.GetCtrlKey (aCtrlKey); | |
3055 if (rc !is XPCOM.NS_OK) error (rc); | |
3056 rc = domKeyEvent.GetShiftKey (aShiftKey); | |
3057 if (rc !is XPCOM.NS_OK) error (rc); | |
3058 rc = domKeyEvent.GetMetaKey (aMetaKey); | |
3059 if (rc !is XPCOM.NS_OK) error (rc); | |
3060 domKeyEvent.Release (); | |
3061 | |
3062 int[] aCharCode = new int[1]; /* PRUint32 */ | |
3063 rc = domKeyEvent.GetCharCode (aCharCode); | |
3064 if (rc !is XPCOM.NS_OK) error (rc); | |
3065 lastCharCode = aCharCode[0]; | |
3066 if (lastCharCode is 0) { | |
3067 switch (lastKeyCode) { | |
3068 case DWT.TAB: lastCharCode = DWT.TAB; break; | |
3069 case DWT.CR: lastCharCode = DWT.CR; break; | |
3070 case DWT.BS: lastCharCode = DWT.BS; break; | |
3071 case DWT.ESC: lastCharCode = DWT.ESC; break; | |
3072 case DWT.DEL: lastCharCode = DWT.DEL; break; | |
3073 } | |
3074 } | |
3075 if (aCtrlKey[0] !is 0 && (0 <= lastCharCode && lastCharCode <= 0x7F)) { | |
3076 if ('a' <= lastCharCode && lastCharCode <= 'z') lastCharCode -= 'a' - 'A'; | |
3077 if (64 <= lastCharCode && lastCharCode <= 95) lastCharCode -= 64; | |
3078 } | |
3079 | |
3080 Event keyEvent = new Event (); | |
3081 keyEvent.widget = browser; | |
3082 keyEvent.type = DWT.KeyDown; | |
3083 keyEvent.keyCode = lastKeyCode; | |
3084 keyEvent.character = (char)lastCharCode; | |
3085 keyEvent.stateMask = (aAltKey[0] !is 0 ? DWT.ALT : 0) | (aCtrlKey[0] !is 0 ? DWT.CTRL : 0) | (aShiftKey[0] !is 0 ? DWT.SHIFT : 0) | (aMetaKey[0] !is 0 ? DWT.COMMAND : 0); | |
3086 browser.notifyListeners (keyEvent.type, keyEvent); | |
3087 if (!keyEvent.doit || browser.isDisposed ()) { | |
3088 domEvent.PreventDefault (); | |
3089 } | |
3090 return XPCOM.NS_OK; | |
3091 } | |
3092 | |
3093 if (XPCOM.DOMEVENT_KEYUP.equals (typeString)) { | |
3094 int /*long*/[] result = new int /*long*/[1]; | |
3095 rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID, result); | |
3096 if (rc !is XPCOM.NS_OK) error (rc); | |
3097 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
3098 nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]); | |
3099 result[0] = 0; | |
3100 | |
3101 int[] aKeyCode = new int[1]; /* PRUint32 */ | |
3102 rc = domKeyEvent.GetKeyCode (aKeyCode); | |
3103 if (rc !is XPCOM.NS_OK) error (rc); | |
3104 int keyCode = translateKey (aKeyCode[0]); | |
3105 if (keyCode is 0) { | |
3106 /* indicates a key for which key events are not sent */ | |
3107 domKeyEvent.Release (); | |
3108 return XPCOM.NS_OK; | |
3109 } | |
3110 if (keyCode !is lastKeyCode) { | |
3111 /* keyup does not correspond to the last keydown */ | |
3112 lastKeyCode = keyCode; | |
3113 lastCharCode = 0; | |
3114 } | |
3115 | |
3116 int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ | |
3117 rc = domKeyEvent.GetAltKey (aAltKey); | |
3118 if (rc !is XPCOM.NS_OK) error (rc); | |
3119 rc = domKeyEvent.GetCtrlKey (aCtrlKey); | |
3120 if (rc !is XPCOM.NS_OK) error (rc); | |
3121 rc = domKeyEvent.GetShiftKey (aShiftKey); | |
3122 if (rc !is XPCOM.NS_OK) error (rc); | |
3123 rc = domKeyEvent.GetMetaKey (aMetaKey); | |
3124 if (rc !is XPCOM.NS_OK) error (rc); | |
3125 domKeyEvent.Release (); | |
3126 | |
3127 Event keyEvent = new Event (); | |
3128 keyEvent.widget = browser; | |
3129 keyEvent.type = DWT.KeyUp; | |
3130 keyEvent.keyCode = lastKeyCode; | |
3131 keyEvent.character = (char)lastCharCode; | |
3132 keyEvent.stateMask = (aAltKey[0] !is 0 ? DWT.ALT : 0) | (aCtrlKey[0] !is 0 ? DWT.CTRL : 0) | (aShiftKey[0] !is 0 ? DWT.SHIFT : 0) | (aMetaKey[0] !is 0 ? DWT.COMMAND : 0); | |
3133 switch (lastKeyCode) { | |
3134 case DWT.SHIFT: | |
3135 case DWT.CONTROL: | |
3136 case DWT.ALT: | |
3137 case DWT.COMMAND: { | |
3138 keyEvent.stateMask |= lastKeyCode; | |
3139 } | |
3140 } | |
3141 browser.notifyListeners (keyEvent.type, keyEvent); | |
3142 if (!keyEvent.doit || browser.isDisposed ()) { | |
3143 domEvent.PreventDefault (); | |
3144 } | |
3145 lastKeyCode = lastCharCode = 0; | |
3146 return XPCOM.NS_OK; | |
3147 } | |
3148 | |
3149 /* mouse event */ | |
3150 | |
3151 int /*long*/[] result = new int /*long*/[1]; | |
3152 rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result); | |
3153 if (rc !is XPCOM.NS_OK) error (rc); | |
3154 if (result[0] is 0) error (XPCOM.NS_NOINTERFACE); | |
3155 nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]); | |
3156 result[0] = 0; | |
3157 | |
3158 /* | |
3159 * MouseOver and MouseOut events are fired any time the mouse enters or exits | |
3160 * any element within the Browser. To ensure that DWT events are only | |
3161 * fired for mouse movements into or out of the Browser, do not fire an | |
3162 * event if the element being exited (on MouseOver) or entered (on MouseExit) | |
3163 * is within the Browser. | |
3164 */ | |
3165 if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString) || XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) { | |
3166 rc = domMouseEvent.GetRelatedTarget (result); | |
3167 if (rc !is XPCOM.NS_OK) error (rc); | |
3168 if (result[0] !is 0) { | |
3169 domMouseEvent.Release (); | |
3170 return XPCOM.NS_OK; | |
3171 } | |
3172 } | |
3173 | |
3174 int[] aClientX = new int[1], aClientY = new int[1], aDetail = new int[1]; /* PRInt32 */ | |
3175 rc = domMouseEvent.GetClientX (aClientX); | |
3176 if (rc !is XPCOM.NS_OK) error (rc); | |
3177 rc = domMouseEvent.GetClientY (aClientY); | |
3178 if (rc !is XPCOM.NS_OK) error (rc); | |
3179 rc = domMouseEvent.GetDetail (aDetail); | |
3180 if (rc !is XPCOM.NS_OK) error (rc); | |
3181 short[] aButton = new short[1]; /* PRUint16 */ | |
3182 rc = domMouseEvent.GetButton (aButton); | |
3183 if (rc !is XPCOM.NS_OK) error (rc); | |
3184 int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ | |
3185 rc = domMouseEvent.GetAltKey (aAltKey); | |
3186 if (rc !is XPCOM.NS_OK) error (rc); | |
3187 rc = domMouseEvent.GetCtrlKey (aCtrlKey); | |
3188 if (rc !is XPCOM.NS_OK) error (rc); | |
3189 rc = domMouseEvent.GetShiftKey (aShiftKey); | |
3190 if (rc !is XPCOM.NS_OK) error (rc); | |
3191 rc = domMouseEvent.GetMetaKey (aMetaKey); | |
3192 if (rc !is XPCOM.NS_OK) error (rc); | |
3193 domMouseEvent.Release (); | |
3194 | |
3195 Event mouseEvent = new Event (); | |
3196 mouseEvent.widget = browser; | |
3197 mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0]; | |
3198 mouseEvent.stateMask = (aAltKey[0] !is 0 ? DWT.ALT : 0) | (aCtrlKey[0] !is 0 ? DWT.CTRL : 0) | (aShiftKey[0] !is 0 ? DWT.SHIFT : 0) | (aMetaKey[0] !is 0 ? DWT.COMMAND : 0); | |
3199 | |
3200 if (XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) { | |
3201 delegate.handleMouseDown (); | |
3202 mouseEvent.type = DWT.MouseDown; | |
3203 mouseEvent.button = aButton[0] + 1; | |
3204 mouseEvent.count = aDetail[0]; | |
3205 } else if (XPCOM.DOMEVENT_MOUSEUP.equals (typeString)) { | |
3206 /* | |
3207 * Bug on OSX. For some reason multiple mouseup events come from the DOM | |
3208 * when button 3 is released on OSX. The first of these events has a count | |
3209 * detail and the others do not. The workaround is to not fire received | |
3210 * button 3 mouseup events that do not have a count since mouse events | |
3211 * without a click count are not valid. | |
3212 */ | |
3213 int button = aButton[0] + 1; | |
3214 int count = aDetail[0]; | |
3215 if (count is 0 && button is 3) return XPCOM.NS_OK; | |
3216 mouseEvent.type = DWT.MouseUp; | |
3217 mouseEvent.button = button; | |
3218 mouseEvent.count = count; | |
3219 } else if (XPCOM.DOMEVENT_MOUSEMOVE.equals (typeString)) { | |
3220 mouseEvent.type = DWT.MouseMove; | |
3221 } else if (XPCOM.DOMEVENT_MOUSEWHEEL.equals (typeString)) { | |
3222 mouseEvent.type = DWT.MouseWheel; | |
3223 mouseEvent.count = -aDetail[0]; | |
3224 } else if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString)) { | |
3225 mouseEvent.type = DWT.MouseEnter; | |
3226 } else if (XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) { | |
3227 mouseEvent.type = DWT.MouseExit; | |
3228 } else if (XPCOM.DOMEVENT_MOUSEDRAG.equals (typeString)) { | |
3229 mouseEvent.type = DWT.DragDetect; | |
3230 mouseEvent.button = aButton[0] + 1; | |
3231 switch (mouseEvent.button) { | |
3232 case 1: mouseEvent.stateMask |= DWT.BUTTON1; break; | |
3233 case 2: mouseEvent.stateMask |= DWT.BUTTON2; break; | |
3234 case 3: mouseEvent.stateMask |= DWT.BUTTON3; break; | |
3235 case 4: mouseEvent.stateMask |= DWT.BUTTON4; break; | |
3236 case 5: mouseEvent.stateMask |= DWT.BUTTON5; break; | |
3237 } | |
3238 } | |
3239 | |
3240 browser.notifyListeners (mouseEvent.type, mouseEvent); | |
3241 if (browser.isDisposed ()) return XPCOM.NS_OK; | |
3242 if (aDetail[0] is 2 && XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) { | |
3243 mouseEvent = new Event (); | |
3244 mouseEvent.widget = browser; | |
3245 mouseEvent.x = aClientX[0]; mouseEvent.y = aClientY[0]; | |
3246 mouseEvent.stateMask = (aAltKey[0] !is 0 ? DWT.ALT : 0) | (aCtrlKey[0] !is 0 ? DWT.CTRL : 0) | (aShiftKey[0] !is 0 ? DWT.SHIFT : 0) | (aMetaKey[0] !is 0 ? DWT.COMMAND : 0); | |
3247 mouseEvent.type = DWT.MouseDoubleClick; | |
3248 mouseEvent.button = aButton[0] + 1; | |
3249 mouseEvent.count = aDetail[0]; | |
3250 browser.notifyListeners (mouseEvent.type, mouseEvent); | |
3251 } | |
3252 return XPCOM.NS_OK; | |
3253 } | |
3254 } |