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 17 18 version(Tango){ 19 import tango.text.locale.Core; 20 import tango.sys.Environment; 21 import tango.stdc..string; 22 } else { // Phobos 23 import std.process: Environment = environment; 24 } 25 26 //import org.eclipse.swt.internal.c.gtk; 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; 55 import org.eclipse.swt.internal.gtk.OS; 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 */ 161 static String GRERANGE_LOWER = "1.8.1.2"; //$NON-NLS-1$ 162 static String GRERANGE_LOWER_FALLBACK = "1.8"; //$NON-NLS-1$ 163 static const bool LowerRangeInclusive = true; 164 static String GRERANGE_UPPER = "1.9.*"; //$NON-NLS-1$ 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 */ 303 mozillaPath = cast(String)greBuffer; 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)); 319 if (Device.DEBUG) getDwtLogger().error (__FILE__, __LINE__, "cannot use detected XULRunner: {}", mozillaPath); //$NON-NLS-1$ 320 321 /* attempt to XPCOMGlueStartup the GRE pointed at by MOZILLA_FIVE_HOME */ 322 auto ptr = Environment.get(XPCOM.MOZILLA_FIVE_HOME); 323 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)); 341 if (Device.DEBUG) getDwtLogger().error( __FILE__, __LINE__, "failed to start as XULRunner: {}", mozillaPath); //$NON-NLS-1$ 342 } 343 } 344 } 345 } 346 if (IsXULRunner) { 347 XPCOMInitWasGlued = true; 348 } 349 } 350 } 351 } 352 353 if (IsXULRunner) { 354 if (Device.DEBUG) getDwtLogger().error( __FILE__, __LINE__, "XULRunner path: {}", mozillaPath); //$NON-NLS-1$ 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 */ 373 auto mozFiveHome = Environment.get(XPCOM.MOZILLA_FIVE_HOME); 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 } 380 if (Device.DEBUG) getDwtLogger().error( __FILE__, __LINE__, "Mozilla path: {}", mozillaPath); //$NON-NLS-1$ 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); 634 prefLocales = String_valueOf(tmpChars[0 .. span]) ~ TOKENIZER_LOCALE; 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 642 version(Tango){ 643 String language = Culture.current.twoLetterLanguageName (); 644 String country = Region.current.twoLetterRegionName (); 645 } else { // Phobos 646 implMissingInPhobos(); 647 String language = "en"; 648 String country = "us"; 649 } 650 String stringBuffer = language._idup(); 651 652 stringBuffer ~= SEPARATOR_LOCALE; 653 stringBuffer ~= country.toLowerCase (); 654 stringBuffer ~= TOKENIZER_LOCALE; 655 stringBuffer ~= language; 656 stringBuffer ~= TOKENIZER_LOCALE; 657 String newLocales = stringBuffer._idup(); 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); 677 (cast(char[])newLocales)[] = stringBuffer[]; 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); 727 prefCharset = String_valueOf(tmpChar[0 .. span]); 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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t 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 //ptrdiff_t 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); 1338 chars = String_valueOf(fromString16z(string)); 1339 } 1340 1341 componentManager.Release (); 1342 document.Release (); 1343 return chars._idup(); 1344 } 1345 1346 extern(D) 1347 public String getUrl () { 1348 if (awaitingNavigate) return ""; //$NON-NLS-1$ 1349 1350 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t 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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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) 1455 static void error (int code, String file, int line) { 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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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) 1896 nsresult QueryInterface (in nsID* riid, void** ppvObject) { 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) 1981 nsresult GetInterface ( in nsID* riid, void** ppvObject) { 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 //ptrdiff_t[] aContentDOMWindow = new ptrdiff_t[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 ptrdiff_t[] {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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] aDOMWindow = new ptrdiff_t[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 //ptrdiff_t[] aTop = new ptrdiff_t[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 //ptrdiff_t 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); 2241 event.text = String_valueOf(fromString16z(aMessage)); 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); 2265 event.text = String_valueOf(fromString16z(status)); 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 //ptrdiff_t[] ret = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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); 2503 event.title = String_valueOf(fromString16z(aTitle)); 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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t 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; 2653 auto size = OS.strlen (aContentType); 2654 if (size > 0) { 2655 //byte[] typeBytes = new byte[size + 1]; 2656 //XPCOM.memmove (typeBytes, aContentType, size); 2657 String contentType = fromStringz(aContentType)._idup(); 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 // ptrdiff_t[] result = new ptrdiff_t[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; 2695 auto categoryBytes = "Gecko-Content-Viewers".ptr; //$NON-NLS-1$ 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); 2747 String text = String_valueOf(fromString16z(aTipText)); 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 //ptrdiff_t 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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 //ptrdiff_t[] result = new ptrdiff_t[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 }