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