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