/******************************************************************************* * Copyright (c) 2003, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.browser; import java.io.*; import java.lang.reflect.*; import java.util.*; import org.eclipse.swt.*; import org.eclipse.swt.widgets.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.internal.*; import org.eclipse.swt.internal.mozilla.*; import org.eclipse.swt.internal.mozilla.init.*; import org.eclipse.swt.layout.*; class Mozilla extends WebBrowser { long /*int*/ embedHandle; nsIWebBrowser webBrowser; Object webBrowserObject; MozillaDelegate delegate; /* Interfaces for this Mozilla embedding notification */ XPCOMObject supports; XPCOMObject weakReference; XPCOMObject webProgressListener; XPCOMObject webProgressListener_17; XPCOMObject webBrowserChrome; XPCOMObject webBrowserChromeFocus; XPCOMObject embeddingSiteWindow; XPCOMObject embeddingSiteWindow_17; XPCOMObject interfaceRequestor; XPCOMObject supportsWeakReference; XPCOMObject contextMenuListener; XPCOMObject uriContentListener; XPCOMObject tooltipListener; XPCOMObject domEventListener; XPCOMObject badCertListener; int chromeFlags = nsIWebBrowserChrome.CHROME_DEFAULT; int registerFunctionsOnState = 0; int refCount, lastKeyCode, lastCharCode, authCount; long /*int*/ request, badCertRequest; Point location, size; boolean visible, isActive, isChild, ignoreDispose, isRetrievingBadCert, isViewingErrorPage, ignoreAllMessages, untrustedText; boolean updateLastNavigateUrl; Shell tip = null; Listener listener; Vector unhookedDOMWindows = new Vector (); String lastNavigateURL; byte[] htmlBytes; static nsIAppShell AppShell; static AppFileLocProvider LocationProvider; static WindowCreator2 WindowCreator; static int BrowserCount, NextJSFunctionIndex = 1; static Hashtable AllFunctions = new Hashtable (); static Listener DisplayListener; static boolean Initialized, IsPre_1_8, IsPre_1_9, IsPre_4, IsPre_17, IsXULRunner, PerformedVersionCheck, XPCOMWasGlued, XPCOMInitWasGlued; static boolean IsGettingSiteWindow; static String MozillaPath; static String oldProxyHostFTP, oldProxyHostHTTP, oldProxyHostSSL; static int oldProxyPortFTP = -1, oldProxyPortHTTP = -1, oldProxyPortSSL = -1, oldProxyType = -1; static byte[] jsLibPathBytes; static byte[] pathBytes_NSFree; /* XULRunner detect constants */ static final String GCC3 = "-gcc3"; //$NON-NLS-1$ static final String GRERANGE_LOWER = "1.8.1.2"; //$NON-NLS-1$ static final String GRERANGE_LOWER_FALLBACK = "1.8"; //$NON-NLS-1$ static final boolean LowerRangeInclusive = true; static final String GRERANGE_UPPER = "1.9.*"; //$NON-NLS-1$ static final boolean UpperRangeInclusive = true; static final String PROPERTY_ABI = "abi"; //$NON-NLS-1$ static final int MAX_PORT = 65535; static final String DEFAULTVALUE_STRING = "default"; //$NON-NLS-1$ static final char SEPARATOR_OS = System.getProperty ("file.separator").charAt (0); //$NON-NLS-1$ static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$ static final String DISPOSE_LISTENER_HOOKED = "org.eclipse.swt.browser.Mozilla.disposeListenerHooked"; //$NON-NLS-1$ static final String HEADER_CONTENTLENGTH = "content-length"; //$NON-NLS-1 static final String HEADER_CONTENTTYPE = "content-type"; //$NON-NLS-1 static final String MIMETYPE_FORMURLENCODED = "application/x-www-form-urlencoded"; //$NON-NLS-1$ static final String MOZILLA_FIVE_HOME = "MOZILLA_FIVE_HOME"; //$NON-NLS-1$ static final String PREFIX_JAVASCRIPT = "javascript:"; //$NON-NLS-1$ static final String PREFERENCE_CHARSET = "intl.charset.default"; //$NON-NLS-1$ static final String PREFERENCE_DISABLEOPENDURINGLOAD = "dom.disable_open_during_load"; //$NON-NLS-1$ static final String PREFERENCE_DISABLEOPENWINDOWSTATUSHIDE = "dom.disable_window_open_feature.status"; //$NON-NLS-1$ static final String PREFERENCE_DISABLEWINDOWSTATUSCHANGE = "dom.disable_window_status_change"; //$NON-NLS-1$ static final String PREFERENCE_JAVASCRIPTENABLED = "javascript.enabled"; //$NON-NLS-1$ static final String PREFERENCE_LANGUAGES = "intl.accept_languages"; //$NON-NLS-1$ static final String PREFERENCE_PROXYHOST_FTP = "network.proxy.ftp"; //$NON-NLS-1$ static final String PREFERENCE_PROXYPORT_FTP = "network.proxy.ftp_port"; //$NON-NLS-1$ static final String PREFERENCE_PROXYHOST_HTTP = "network.proxy.http"; //$NON-NLS-1$ static final String PREFERENCE_PROXYPORT_HTTP = "network.proxy.http_port"; //$NON-NLS-1$ static final String PREFERENCE_PROXYHOST_SSL = "network.proxy.ssl"; //$NON-NLS-1$ static final String PREFERENCE_PROXYPORT_SSL = "network.proxy.ssl_port"; //$NON-NLS-1$ static final String PREFERENCE_PROXYTYPE = "network.proxy.type"; //$NON-NLS-1$ static final String PROFILE_AFTER_CHANGE = "profile-after-change"; //$NON-NLS-1$ static final String PROFILE_BEFORE_CHANGE = "profile-before-change"; //$NON-NLS-1$ static final String PROFILE_DIR = SEPARATOR_OS + "eclipse" + SEPARATOR_OS; //$NON-NLS-1$ static final String PROFILE_DO_CHANGE = "profile-do-change"; //$NON-NLS-1$ static final String PROPERTY_PROXYPORT = "network.proxy_port"; //$NON-NLS-1$ static final String PROPERTY_PROXYHOST = "network.proxy_host"; //$NON-NLS-1$ static final String SEPARATOR_LOCALE = "-"; //$NON-NLS-1$ static final String SHUTDOWN_PERSIST = "shutdown-persist"; //$NON-NLS-1$ static final String STARTUP = "startup"; //$NON-NLS-1$ static final String TOKENIZER_LOCALE = ","; //$NON-NLS-1$ static final String TRUE = "true"; //$NON-NLS-1$ static final String URI_FILEROOT = "file:///"; //$NON-NLS-1$ static final String MOZILLA_PROFILE_PATH = "org.eclipse.swt.browser.MOZ_PROFILE_PATH"; //$NON-NLS-1$ static final String XULRUNNER_PATH = "org.eclipse.swt.browser.XULRunnerPath"; //$NON-NLS-1$ // TEMPORARY CODE static final String FACTORIES_REGISTERED = "org.eclipse.swt.browser.MozillaFactoriesRegistered"; //$NON-NLS-1$ static final String GRE_INITIALIZED = "org.eclipse.swt.browser.XULRunnerInitialized"; //$NON-NLS-1$ static { DisplayListener = new Listener () { public void handleEvent (Event event) { if (BrowserCount > 0) return; /* another display is still active */ long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIObserverService observerService = new nsIObserverService (result[0]); result[0] = 0; buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_BEFORE_CHANGE, true); int length = SHUTDOWN_PERSIST.length (); char[] chars = new char [length + 1]; SHUTDOWN_PERSIST.getChars (0, length, chars, 0); rc = observerService.NotifyObservers (0, buffer, chars); if (rc != XPCOM.NS_OK) error (rc); observerService.Release (); if (LocationProvider != null) { String prefsLocation = LocationProvider.profilePath + AppFileLocProvider.PREFERENCES_FILE; nsEmbedString pathString = new nsEmbedString (prefsLocation); rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, result); if (rc != XPCOM.NS_OK) Mozilla.error (rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_ERROR_NULL_POINTER); pathString.dispose (); nsILocalFile localFile = new nsILocalFile (result [0]); result[0] = 0; rc = localFile.QueryInterface (IsPre_17 ? nsIFile.NS_IFILE_IID : nsIFile.NS_IFILE_17_IID, result); if (rc != XPCOM.NS_OK) Mozilla.error (rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_ERROR_NO_INTERFACE); localFile.Release (); nsIFile prefFile = new nsIFile (result[0]); result[0] = 0; buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (buffer, nsIPrefService.NS_IPREFSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIPrefService prefService = new nsIPrefService (result[0]); result[0] = 0; revertProxySettings (prefService); rc = prefService.SavePrefFile (prefFile.getAddress ()); prefService.Release (); prefFile.Release (); } serviceManager.Release (); if (XPCOMWasGlued) { /* * The following is intentionally commented because it causes subsequent * browser instantiations within the process to fail. Mozilla does not * support being unloaded and then re-initialized in a process, see * http://www.mail-archive.com/dev-embedding@lists.mozilla.org/msg01732.html . */ // int size = XPCOM.nsDynamicFunctionLoad_sizeof (); // /* alloc memory for two structs, the second is empty to signify the end of the list */ // long /*int*/ ptr = C.malloc (size * 2); // C.memset (ptr, 0, size * 2); // nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad (); // byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_TermEmbedding", true); //$NON-NLS-1$ // functionLoad.functionName = C.malloc (bytes.length); // C.memmove (functionLoad.functionName, bytes, bytes.length); // functionLoad.function = C.malloc (C.PTR_SIZEOF); // C.memmove (functionLoad.function, new long /*int*/[] {0} , C.PTR_SIZEOF); // XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); // XPCOM.XPCOMGlueLoadXULFunctions (ptr); // C.memmove (result, functionLoad.function, C.PTR_SIZEOF); // long /*int*/ functionPtr = result[0]; // result[0] = 0; // C.free (functionLoad.function); // C.free (functionLoad.functionName); // C.free (ptr); // XPCOM.Call (functionPtr); // XPCOM.XPCOMGlueShutdown (); XPCOMWasGlued = false; } if (XPCOMInitWasGlued) { XPCOMInit.XPCOMGlueShutdown (); XPCOMInitWasGlued = false; } Initialized = PerformedVersionCheck = false; } void revertProxySettings (nsIPrefService prefService) { /* the proxy settings are typically not set, so check for this first */ boolean hostSet = oldProxyHostFTP != null || oldProxyHostHTTP != null || oldProxyHostSSL != null; if (!hostSet && oldProxyPortFTP == -1 && oldProxyPortHTTP == -1 && oldProxyPortSSL == -1 && oldProxyType == -1) return; long /*int*/[] result = new long /*int*/[1]; byte[] buffer = new byte[1]; int rc = prefService.GetBranch (buffer, result); /* empty buffer denotes root preference level */ if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIPrefBranch prefBranch = new nsIPrefBranch (result[0]); result[0] = 0; if (hostSet) { rc = XPCOM.NS_GetComponentManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIComponentManager componentManager = new nsIComponentManager (result[0]); result[0] = 0; byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIPrefLocalizedString localizedString = new nsIPrefLocalizedString (result[0]); result[0] = 0; if (oldProxyHostFTP != null) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_FTP, true); if (oldProxyHostFTP.equals (DEFAULTVALUE_STRING)) { rc = prefBranch.ClearUserPref (buffer); if (rc != XPCOM.NS_OK) error (rc); } else { int length = oldProxyHostFTP.length (); char[] charBuffer = new char[length]; oldProxyHostFTP.getChars (0, length, charBuffer, 0); rc = localizedString.SetDataWithLength (length, charBuffer); if (rc != XPCOM.NS_OK) error (rc); rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); } } if (oldProxyHostHTTP != null) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_HTTP, true); if (oldProxyHostHTTP.equals (DEFAULTVALUE_STRING)) { rc = prefBranch.ClearUserPref (buffer); if (rc != XPCOM.NS_OK) error (rc); } else { int length = oldProxyHostHTTP.length (); char[] charBuffer = new char[length]; oldProxyHostHTTP.getChars (0, length, charBuffer, 0); rc = localizedString.SetDataWithLength (length, charBuffer); if (rc != XPCOM.NS_OK) error (rc); rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); } } if (oldProxyHostSSL != null) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_SSL, true); if (oldProxyHostSSL.equals (DEFAULTVALUE_STRING)) { rc = prefBranch.ClearUserPref (buffer); if (rc != XPCOM.NS_OK) error (rc); } else { int length = oldProxyHostSSL.length (); char[] charBuffer = new char[length]; oldProxyHostSSL.getChars (0, length, charBuffer, 0); rc = localizedString.SetDataWithLength (length, charBuffer); if (rc != XPCOM.NS_OK) error (rc); rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); } } localizedString.Release (); componentManager.Release (); } if (oldProxyPortFTP != -1) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_FTP, true); rc = prefBranch.SetIntPref (buffer, oldProxyPortFTP); if (rc != XPCOM.NS_OK) error (rc); } if (oldProxyPortHTTP != -1) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_HTTP, true); rc = prefBranch.SetIntPref (buffer, oldProxyPortHTTP); if (rc != XPCOM.NS_OK) error (rc); } if (oldProxyPortSSL != -1) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_SSL, true); rc = prefBranch.SetIntPref (buffer, oldProxyPortSSL); if (rc != XPCOM.NS_OK) error (rc); } if (oldProxyType != -1) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYTYPE, true); rc = prefBranch.SetIntPref (buffer, oldProxyType); if (rc != XPCOM.NS_OK) error (rc); } prefBranch.Release (); } }; MozillaClearSessions = new Runnable () { public void run () { if (!Initialized) return; long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIEMANAGER_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsICookieManager.NS_ICOOKIEMANAGER_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); serviceManager.Release (); nsICookieManager manager = new nsICookieManager (result[0]); result[0] = 0; rc = manager.GetEnumerator (result); if (rc != XPCOM.NS_OK) error (rc); nsISimpleEnumerator enumerator = new nsISimpleEnumerator (result[0]); int[] moreElements = new int[1]; /* PRBool */ rc = enumerator.HasMoreElements (moreElements); if (rc != XPCOM.NS_OK) error (rc); while (moreElements[0] != 0) { result[0] = 0; rc = enumerator.GetNext (result); if (rc != XPCOM.NS_OK) error (rc); nsICookie cookie = new nsICookie (result[0]); long[] expires = new long[1]; rc = cookie.GetExpires (expires); if (expires[0] == 0) { /* indicates a session cookie */ long /*int*/ domain = XPCOM.nsEmbedCString_new (); long /*int*/ name = XPCOM.nsEmbedCString_new (); long /*int*/ path = XPCOM.nsEmbedCString_new (); cookie.GetHost (domain); cookie.GetName (name); cookie.GetPath (path); rc = manager.Remove (domain, name, path, 0); XPCOM.nsEmbedCString_delete (domain); XPCOM.nsEmbedCString_delete (name); XPCOM.nsEmbedCString_delete (path); if (rc != XPCOM.NS_OK) error (rc); } cookie.Release (); rc = enumerator.HasMoreElements (moreElements); if (rc != XPCOM.NS_OK) error (rc); } enumerator.Release (); manager.Release (); } }; MozillaGetCookie = new Runnable() { public void run() { if (!Initialized) return; long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIIOService ioService = new nsIIOService (result[0]); result[0] = 0; byte[] bytes = MozillaDelegate.wcsToMbcs (null, CookieUrl, false); long /*int*/ aSpec = XPCOM.nsEmbedCString_new (bytes, bytes.length); rc = ioService.NewURI (aSpec, null, 0, result); XPCOM.nsEmbedCString_delete (aSpec); ioService.Release (); if (rc != XPCOM.NS_OK) { serviceManager.Release (); return; } if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); nsIURI aURI = new nsIURI (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIESERVICE_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService.NS_ICOOKIESERVICE_IID, result); long /*int*/ cookieString; if (rc == XPCOM.NS_OK && result[0] != 0) { nsICookieService cookieService = new nsICookieService (result[0]); result[0] = 0; rc = cookieService.GetCookieString (aURI.getAddress(), 0, result); cookieService.Release (); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) { aURI.Release (); serviceManager.Release (); return; } cookieString = result[0]; } else { result[0] = 0; rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService_1_9.NS_ICOOKIESERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsICookieService_1_9 cookieService = new nsICookieService_1_9 (result[0]); result[0] = 0; rc = cookieService.GetCookieString(aURI.getAddress(), 0, result); cookieService.Release (); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) { aURI.Release (); serviceManager.Release (); return; } cookieString = result[0]; } aURI.Release (); serviceManager.Release (); result[0] = 0; int length = C.strlen (cookieString); bytes = new byte[length]; XPCOM.memmove (bytes, cookieString, length); /* * NS_Free was introduced in mozilla 1.8, prior to this the standard free() call * was to be used. Try to free the cookie string with NS_Free first, and if it fails * then assume that an older mozilla is being used, and use C's free() instead. */ if (pathBytes_NSFree == null) { String mozillaPath = getMozillaPath () + MozillaDelegate.getLibraryName () + '\0'; try { pathBytes_NSFree = mozillaPath.getBytes ("UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { pathBytes_NSFree = mozillaPath.getBytes (); } } if (!XPCOM.NS_Free (pathBytes_NSFree, cookieString)) { C.free (cookieString); } String allCookies = new String (MozillaDelegate.mbcsToWcs (null, bytes)); StringTokenizer tokenizer = new StringTokenizer (allCookies, ";"); //$NON-NLS-1$ while (tokenizer.hasMoreTokens ()) { String cookie = tokenizer.nextToken (); int index = cookie.indexOf ('='); if (index != -1) { String name = cookie.substring (0, index).trim (); if (name.equals (CookieName)) { CookieValue = cookie.substring (index + 1).trim (); return; } } } } }; MozillaSetCookie = new Runnable() { public void run() { if (!Initialized) return; long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIIOService ioService = new nsIIOService (result[0]); result[0] = 0; byte[] bytes = MozillaDelegate.wcsToMbcs (null, CookieUrl, false); long /*int*/ aSpec = XPCOM.nsEmbedCString_new (bytes, bytes.length); rc = ioService.NewURI (aSpec, null, 0, result); XPCOM.nsEmbedCString_delete (aSpec); ioService.Release (); if (rc != XPCOM.NS_OK) { serviceManager.Release (); return; } if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); nsIURI aURI = new nsIURI(result[0]); result[0] = 0; byte[] aCookie = MozillaDelegate.wcsToMbcs (null, CookieValue, true); byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_COOKIESERVICE_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService.NS_ICOOKIESERVICE_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsICookieService cookieService = new nsICookieService (result[0]); rc = cookieService.SetCookieString (aURI.getAddress(), 0, aCookie, 0); cookieService.Release (); } else { result[0] = 0; rc = serviceManager.GetServiceByContractID (aContractID, nsICookieService_1_9.NS_ICOOKIESERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsICookieService_1_9 cookieService = new nsICookieService_1_9 (result[0]); rc = cookieService.SetCookieString(aURI.getAddress(), 0, aCookie, 0); cookieService.Release (); } result[0] = 0; aURI.Release (); serviceManager.Release (); CookieResult = rc == 0; } }; } static String Arch () { String osArch = System.getProperty("os.arch"); //$NON-NLS-1$ if (osArch.equals ("i386") || osArch.equals ("i686")) return "x86"; //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ if (osArch.equals ("amd64")) return "x86_64"; //$NON-NLS-1$ $NON-NLS-2$ if (osArch.equals ("IA64N")) return "ia64_32"; //$NON-NLS-1$ $NON-NLS-2$ if (osArch.equals ("IA64W")) return "ia64"; //$NON-NLS-1$ $NON-NLS-2$ return osArch; } static String OS() { String osName = System.getProperty("os.name"); //$NON-NLS-1$ if (osName.equals ("Linux")) return "linux"; //$NON-NLS-1$ $NON-NLS-2$ if (osName.equals ("AIX")) return "aix"; //$NON-NLS-1$ $NON-NLS-2$ if (osName.equals ("Solaris") || osName.equals ("SunOS")) return "solaris"; //$NON-NLS-1$ $NON-NLS-2$ $NON-NLS-3$ if (osName.equals ("HP-UX")) return "hpux"; //$NON-NLS-1$ $NON-NLS-2$ if (osName.equals ("Mac OS X")) return "macosx"; //$NON-NLS-1$ $NON-NLS-2$ if (osName.startsWith ("Win")) return "win32"; //$NON-NLS-1$ $NON-NLS-2$ return osName; } static void LoadLibraries () { boolean initLoaded = false; if (Boolean.getBoolean (GRE_INITIALIZED)) { /* * Another browser has already initialized xulrunner in this process, * so just bind to it instead of trying to initialize a new one. */ Initialized = true; } MozillaPath = System.getProperty (XULRUNNER_PATH); /* * Browser clients that ship XULRunner in a plug-in must have an opportunity * to set the org.eclipse.swt.browser.XULRunnerPath system property to point * at their XULRunner before the first Mozilla-based Browser is created. To * facilitate this, reflection is used to reference non-existent class * org.eclipse.swt.browser.XULRunnerInitializer the first time a Mozilla- * based Browser is created. A client wishing to use this hook can do so * by creating a fragment of org.eclipse.swt that implements this class and * sets the system property in its static initializer. */ if (MozillaPath == null) { try { Class.forName ("org.eclipse.swt.browser.XULRunnerInitializer"); //$NON-NLS-1$ MozillaPath = System.getProperty (XULRUNNER_PATH); } catch (ClassNotFoundException e) { /* no fragment is providing this class, which is the typical case */ } } if (MozillaPath == null) { try { String libName = MozillaDelegate.getSWTInitLibraryName (); Library.loadLibrary (libName); initLoaded = true; } catch (UnsatisfiedLinkError e) { /* * If this library failed to load then do not attempt to detect a * xulrunner to use. The Browser may still be usable if MOZILLA_FIVE_HOME * points at a GRE. */ } } else { /* ensure that client-supplied path is using correct separators */ if (SEPARATOR_OS == '/') { MozillaPath = MozillaPath.replace ('\\', SEPARATOR_OS); } else { MozillaPath = MozillaPath.replace ('/', SEPARATOR_OS); } MozillaPath += SEPARATOR_OS + MozillaDelegate.getLibraryName (); IsXULRunner = true; } if (initLoaded) { /* attempt to discover a XULRunner to use as the GRE */ MozillaPath = InitDiscoverXULRunner (); IsXULRunner = MozillaPath.length () > 0; /* * Test whether the detected XULRunner can be used as the GRE before loading swt's * XULRunner library. If it cannot be used then fall back to attempting to use * the GRE pointed to by MOZILLA_FIVE_HOME. * * One case where this will fail is attempting to use a 64-bit xulrunner while swt * is running in 32-bit mode, or vice versa. */ if (IsXULRunner) { byte[] bytes = MozillaDelegate.wcsToMbcs (null, MozillaPath, true); int rc = XPCOMInit.XPCOMGlueStartup (bytes); if (rc != XPCOM.NS_OK) { MozillaPath = MozillaPath.substring (0, MozillaPath.lastIndexOf (SEPARATOR_OS)); if (Device.DEBUG) System.out.println ("cannot use detected XULRunner: " + MozillaPath); //$NON-NLS-1$ /* attempt to XPCOMGlueStartup the GRE pointed at by MOZILLA_FIVE_HOME */ long /*int*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, MOZILLA_FIVE_HOME, true)); if (ptr == 0) { IsXULRunner = false; } else { int length = C.strlen (ptr); bytes = new byte[length]; C.memmove (bytes, ptr, length); MozillaPath = new String (MozillaDelegate.mbcsToWcs (null, bytes)); /* * Attempting to XPCOMGlueStartup a mozilla-based GRE != xulrunner can * crash, so don't attempt unless the GRE appears to be xulrunner. */ if (MozillaPath.indexOf ("xulrunner") == -1) { //$NON-NLS-1$ IsXULRunner = false; } else { MozillaPath += SEPARATOR_OS + MozillaDelegate.getLibraryName (); bytes = MozillaDelegate.wcsToMbcs (null, MozillaPath, true); rc = XPCOMInit.XPCOMGlueStartup (bytes); if (rc == XPCOM.NS_OK) { /* ensure that client-supplied path is using correct separators */ if (SEPARATOR_OS == '/') { MozillaPath = MozillaPath.replace ('\\', SEPARATOR_OS); } else { MozillaPath = MozillaPath.replace ('/', SEPARATOR_OS); } } else { IsXULRunner = false; MozillaPath = MozillaPath.substring (0, MozillaPath.lastIndexOf (SEPARATOR_OS)); if (Device.DEBUG) System.out.println ("failed to start as XULRunner: " + MozillaPath); //$NON-NLS-1$ } } } } if (IsXULRunner) { XPCOMInitWasGlued = true; } } } } public void create (Composite parent, int style) { delegate = new MozillaDelegate (browser); final Display display = parent.getDisplay (); long /*int*/[] result = new long /*int*/[1]; if (!Initialized) { LoadLibraries (); if (IsXULRunner) { /* load swt's xulrunner library and invoke XPCOMGlueStartup to load xulrunner's dependencies */ MozillaPath = initXULRunner (MozillaPath); } else { /* * If style SWT.MOZILLA was specified then this initialization has already * failed, because SWT.MOZILLA-style Browsers must utilize XULRunner. */ if ((style & SWT.MOZILLA) != 0) { browser.dispose (); String errorString = (MozillaPath != null && MozillaPath.length () > 0) ? " [Failed to use detected XULRunner: " + MozillaPath + "]" : " [Could not detect registered XULRunner to use]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ SWT.error (SWT.ERROR_NO_HANDLES, null, errorString); } /* load swt's mozilla library */ MozillaPath = initMozilla (MozillaPath); } if (!Initialized) { /* create LocationProvider, which tells mozilla where to find things on the file system */ String profilePath = System.getProperty (MOZILLA_PROFILE_PATH); if (profilePath != null && profilePath.length() > 0) { /* ensure that client-supplied path is using correct separators */ if (SEPARATOR_OS == '/') { profilePath = profilePath.replace ('\\', SEPARATOR_OS); } else { profilePath = profilePath.replace ('/', SEPARATOR_OS); } } else { profilePath = MozillaDelegate.getProfilePath (); } String cacheParentPath = MozillaDelegate.getCacheParentPath (); LocationProvider = new AppFileLocProvider (MozillaPath, profilePath, cacheParentPath, IsXULRunner); LocationProvider.AddRef (); /* write external.xpt to the file system if needed */ initExternal (LocationProvider.profilePath); /* invoke appropriate Init function (based on mozilla version) */ initXPCOM (MozillaPath, IsXULRunner); } /* attempt to initialize JavaXPCOM in the detected XULRunner */ if (IsXULRunner) initJavaXPCOM (MozillaPath); /* get the nsIComponentManager and nsIServiceManager, used throughout initialization */ int rc = XPCOM.NS_GetComponentManager (result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIComponentManager componentManager = new nsIComponentManager (result[0]); result[0] = 0; rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; /* init the event handler if needed */ initSpinup (componentManager); /* * Check for the property indicating that factories have already been registered, * in which case this browser should not overwrite them with its own. */ boolean factoriesRegistered = Boolean.getBoolean (FACTORIES_REGISTERED); /* init our WindowCreator, which mozilla uses for the creation of child browsers in external Shells */ if (!factoriesRegistered) { initWindowCreator (serviceManager); } /* notify mozilla that the profile directory has been changed from its default value */ initProfile (serviceManager, IsXULRunner); /* init preference values that give desired mozilla behaviours */ initPreferences (serviceManager, componentManager); /* init our various factories that mozilla can invoke as needed */ if (!factoriesRegistered) { initFactories (serviceManager, componentManager, IsXULRunner); } serviceManager.Release (); componentManager.Release (); /* add cookies that were set by a client before the first Mozilla instance was created */ if (MozillaPendingCookies != null) { SetPendingCookies (MozillaPendingCookies); } MozillaPendingCookies = null; Initialized = true; } BrowserCount++; if (display.getData (DISPOSE_LISTENER_HOOKED) == null) { display.setData (DISPOSE_LISTENER_HOOKED, DISPOSE_LISTENER_HOOKED); display.addListener (SWT.Dispose, DisplayListener); } /* get the nsIComponentManager, used throughout initialization */ int rc = XPCOM.NS_GetComponentManager (result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIComponentManager componentManager = new nsIComponentManager (result[0]); result[0] = 0; /* create the nsIWebBrowser instance */ rc = componentManager.CreateInstance (XPCOM.NS_IWEBBROWSER_CID, 0, nsIWebBrowser.NS_IWEBBROWSER_10_IID, result); if (rc != XPCOM.NS_OK) { rc = componentManager.CreateInstance (XPCOM.NS_IWEBBROWSER_CID, 0, nsIWebBrowser.NS_IWEBBROWSER_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } webBrowser = new nsIWebBrowser (result[0]); result[0] = 0; /* create the instance-based callback interfaces */ createCOMInterfaces (); AddRef (); /* init the nsIWebBrowser's container and base windows */ initWebBrowserWindows (); if (!PerformedVersionCheck) { /* IsPre_4 and IsPre_17 are already determined in initXPCOM() */ PerformedVersionCheck = true; rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]); result[0] = 0; /* * Check for the property indicating that factories have already been registered, * in which case this browser should not overwrite them with its own. */ boolean factoriesRegistered = Boolean.getBoolean (FACTORIES_REGISTERED); /* * Check for the availability of the pre-1.8 implementation of nsIDocShell * to determine if the GRE's version is < 1.8. */ rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (XPCOM.NS_ERROR_FAILURE); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_ERROR_NO_INTERFACE); } nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]); result[0] = 0; rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { IsPre_1_8 = true; new nsISupports (result[0]).Release (); } IsPre_1_9 = true; result[0] = 0; /* * A Download factory for contract "Transfer" must be registered iff the GRE's version is 1.8.x. * Check for the availability of the 1.8 implementation of nsIDocShell to determine if the * GRE's version is 1.8.x. * If the GRE version is < 1.8 then the previously-registered Download factory for contract * "Download" will be used. * If the GRE version is >= 1.9 then no Download factory is registered because this * functionality is provided by the GRE. */ if (!IsPre_1_8) { rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_1_8_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { /* 1.8.x */ new nsISupports (result[0]).Release (); result[0] = 0; if (!factoriesRegistered) { DownloadFactory_1_8 downloadFactory_1_8 = new DownloadFactory_1_8 (); downloadFactory_1_8.AddRef (); byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_TRANSFER_CONTRACTID, true); byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "swtTransfer", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory_1_8.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } downloadFactory_1_8.Release (); } } else { /* >= 1.9.x */ IsPre_1_9 = false; } } result[0] = 0; interfaceRequestor.Release (); componentRegistrar.Release (); if (!factoriesRegistered) { HelperAppLauncherDialogFactory dialogFactory = new HelperAppLauncherDialogFactory (); dialogFactory.AddRef (); byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CONTRACTID, true); byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "swtHelperAppLauncherDialog", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_HELPERAPPLAUNCHERDIALOG_CID, aClassName, aContractID, dialogFactory.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } dialogFactory.Release (); } System.setProperty (FACTORIES_REGISTERED, TRUE); } componentManager.Release (); /* * Bug in XULRunner 1.9. On win32, Mozilla does not clear its background before content has * been set into it. As a result, embedders appear broken if they do not immediately display * a URL or text. The Mozilla bug for this is https://bugzilla.mozilla.org/show_bug.cgi?id=453523. * * The workaround is to subclass the Mozilla window and clear it whenever WM_ERASEBKGND is received. * This subclass should be removed once content has been set into the browser. */ if (!IsPre_1_9) { delegate.addWindowSubclass (); } /* add listeners for progress and content */ rc = webBrowser.AddWebBrowserListener (weakReference.getAddress (), IsPre_17 ? nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID : nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_17_IID); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } rc = webBrowser.SetParentURIContentListener (uriContentListener.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } delegate.init (); listener = new Listener () { public void handleEvent (Event event) { switch (event.type) { case SWT.Dispose: { /* make this handler run after other dispose listeners */ if (ignoreDispose) { ignoreDispose = false; break; } ignoreDispose = true; browser.notifyListeners (event.type, event); event.type = SWT.NONE; onDispose (event.display); break; } case SWT.Resize: onResize (); break; case SWT.FocusIn: { Activate (); /* if tabbing onto a page for the first time then full-Browser focus ring should be shown */ long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_FOCUSMANAGER_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, !IsPre_4 ? nsIFocusManager.NS_IFOCUSMANAGER_10_IID : nsIFocusManager.NS_IFOCUSMANAGER_IID, result); serviceManager.Release (); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIFocusManager focusManager = new nsIFocusManager (result[0]); result[0] = 0; rc = focusManager.GetFocusedElement (result); if (rc == XPCOM.NS_OK) { if (result[0] != 0) { new nsISupports (result[0]).Release (); result[0] = 0; } else { /* show full browser focus ring */ rc = webBrowser.GetContentDOMWindow (result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIDOMWindow domWindow = new nsIDOMWindow (result[0]); result[0] = 0; rc = domWindow.GetDocument (result); domWindow.Release (); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIDOMDocument domDocument = new nsIDOMDocument (result[0]); result[0] = 0; rc = domDocument.GetDocumentElement (result); domDocument.Release (); if (rc == XPCOM.NS_OK && result[0] != 0) { rc = focusManager.SetFocus (result[0], nsIFocusManager.FLAG_BYKEY); new nsISupports(result[0]).Release (); result[0] = 0; } } } } } focusManager.Release (); } break; } case SWT.Activate: Activate (); break; case SWT.Deactivate: { Display display = event.display; if (Mozilla.this.browser == display.getFocusControl ()) Deactivate (); break; } case SWT.Show: { /* * Feature in GTK Mozilla. Mozilla does not show up when * its container (a GTK fixed handle) is made visible * after having been hidden. The workaround is to reset * its size after the container has been made visible. */ Display display = event.display; display.asyncExec(new Runnable () { public void run() { if (browser.isDisposed ()) return; onResize (); } }); break; } } } }; int[] folderEvents = new int[] { SWT.Dispose, SWT.Resize, SWT.FocusIn, SWT.Activate, SWT.Deactivate, SWT.Show, SWT.KeyDown, /* needed to make browser traversable */ }; for (int i = 0; i < folderEvents.length; i++) { browser.addListener (folderEvents[i], listener); } } public boolean back () { htmlBytes = null; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); rc = webNavigation.GoBack (); webNavigation.Release (); return rc == XPCOM.NS_OK; } public boolean close () { final boolean[] result = new boolean[] {false}; LocationListener[] oldListeners = locationListeners; locationListeners = new LocationListener[] { new LocationAdapter () { public void changing (LocationEvent event) { /* implies that the user did not veto the page unload */ result[0] = true; } } }; execute ("window.location.replace('about:blank');"); //$NON-NLS-1$ locationListeners = oldListeners; return result[0]; } void createCOMInterfaces () { // Create each of the interfaces that this object implements supports = new XPCOMObject (new int[] {2, 0, 0}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} }; weakReference = new XPCOMObject (new int[] {2, 0, 0, 2}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return QueryReferent (args[0], args[1]);} }; webProgressListener = new XPCOMObject (new int[] {2, 0, 0, 4, 6, 3, 4, 3}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return OnStateChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3]);} public long /*int*/ method4 (long /*int*/[] args) {return OnProgressChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4], (int)/*64*/args[5]);} public long /*int*/ method5 (long /*int*/[] args) {return OnLocationChange (args[0], args[1], args[2]);} public long /*int*/ method6 (long /*int*/[] args) {return OnStatusChange (args[0], args[1], (int)/*64*/args[2], args[3]);} public long /*int*/ method7 (long /*int*/[] args) {return OnSecurityChange (args[0], args[1], (int)/*64*/args[2]);} }; webProgressListener_17 = new XPCOMObject (new int[] {2, 0, 0, 4, 6, 4, 4, 3}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return OnStateChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3]);} public long /*int*/ method4 (long /*int*/[] args) {return OnProgressChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4], (int)/*64*/args[5]);} public long /*int*/ method5 (long /*int*/[] args) {return OnLocationChange (args[0], args[1], args[2], (int)/*64*/args[3]);} public long /*int*/ method6 (long /*int*/[] args) {return OnStatusChange (args[0], args[1], (int)/*64*/args[2], args[3]);} public long /*int*/ method7 (long /*int*/[] args) {return OnSecurityChange (args[0], args[1], (int)/*64*/args[2]);} }; webBrowserChrome = new XPCOMObject (new int[] {2, 0, 0, 2, 1, 1, 1, 1, 0, 2, 0, 1, 1}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return SetStatus ((int)/*64*/args[0], args[1]);} public long /*int*/ method4 (long /*int*/[] args) {return GetWebBrowser (args[0]);} public long /*int*/ method5 (long /*int*/[] args) {return SetWebBrowser (args[0]);} public long /*int*/ method6 (long /*int*/[] args) {return GetChromeFlags (args[0]);} public long /*int*/ method7 (long /*int*/[] args) {return SetChromeFlags ((int)/*64*/args[0]);} public long /*int*/ method8 (long /*int*/[] args) {return DestroyBrowserWindow ();} public long /*int*/ method9 (long /*int*/[] args) {return SizeBrowserTo ((int)/*64*/args[0], (int)/*64*/args[1]);} public long /*int*/ method10 (long /*int*/[] args) {return ShowAsModal ();} public long /*int*/ method11 (long /*int*/[] args) {return IsWindowModal (args[0]);} public long /*int*/ method12 (long /*int*/[] args) {return ExitModalEventLoop ((int)/*64*/args[0]);} }; webBrowserChromeFocus = new XPCOMObject (new int[] {2, 0, 0, 0, 0}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return FocusNextElement ();} public long /*int*/ method4 (long /*int*/[] args) {return FocusPrevElement ();} }; embeddingSiteWindow = new XPCOMObject (new int[] {2, 0, 0, 5, 5, 0, 1, 1, 1, 1, 1}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return SetDimensions ((int)/*64*/args[0], (int)/*64*/args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4]);} public long /*int*/ method4 (long /*int*/[] args) {return GetDimensions ((int)/*64*/args[0], args[1], args[2], args[3], args[4]);} public long /*int*/ method5 (long /*int*/[] args) {return SetFocus ();} public long /*int*/ method6 (long /*int*/[] args) {return GetVisibility (args[0]);} public long /*int*/ method7 (long /*int*/[] args) {return SetVisibility ((int)/*64*/args[0]);} public long /*int*/ method8 (long /*int*/[] args) {return GetTitle (args[0]);} public long /*int*/ method9 (long /*int*/[] args) {return SetTitle (args[0]);} public long /*int*/ method10 (long /*int*/[] args) {return GetSiteWindow (args[0]);} }; embeddingSiteWindow_17 = new XPCOMObject (new int[] {2, 0, 0, 5, 5, 0, 1, 1, 1, 1, 1, 0}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return SetDimensions ((int)/*64*/args[0], (int)/*64*/args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4]);} public long /*int*/ method4 (long /*int*/[] args) {return GetDimensions ((int)/*64*/args[0], args[1], args[2], args[3], args[4]);} public long /*int*/ method5 (long /*int*/[] args) {return SetFocus ();} public long /*int*/ method6 (long /*int*/[] args) {return GetVisibility (args[0]);} public long /*int*/ method7 (long /*int*/[] args) {return SetVisibility ((int)/*64*/args[0]);} public long /*int*/ method8 (long /*int*/[] args) {return GetTitle (args[0]);} public long /*int*/ method9 (long /*int*/[] args) {return SetTitle (args[0]);} public long /*int*/ method10 (long /*int*/[] args) {return GetSiteWindow (args[0]);} public long /*int*/ method11 (long /*int*/[] args) {return Blur ();} }; interfaceRequestor = new XPCOMObject (new int[] {2, 0, 0, 2} ){ public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return GetInterface (args[0], args[1]);} }; supportsWeakReference = new XPCOMObject (new int[] {2, 0, 0, 1}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return GetWeakReference (args[0]);} }; contextMenuListener = new XPCOMObject (new int[] {2, 0, 0, 3}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return OnShowContextMenu ((int)/*64*/args[0], args[1], args[2]);} }; uriContentListener = new XPCOMObject (new int[] {2, 0, 0, 2, 5, 3, 4, 1, 1, 1, 1}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return OnStartURIOpen (args[0], args[1]);} public long /*int*/ method4 (long /*int*/[] args) {return DoContent (args[0], (int)/*64*/args[1], args[2], args[3], args[4]);} public long /*int*/ method5 (long /*int*/[] args) {return IsPreferred (args[0], args[1], args[2]);} public long /*int*/ method6 (long /*int*/[] args) {return CanHandleContent (args[0], (int)/*64*/args[1], args[2], args[3]);} public long /*int*/ method7 (long /*int*/[] args) {return GetLoadCookie (args[0]);} public long /*int*/ method8 (long /*int*/[] args) {return SetLoadCookie (args[0]);} public long /*int*/ method9 (long /*int*/[] args) {return GetParentContentListener (args[0]);} public long /*int*/ method10 (long /*int*/[] args) {return SetParentContentListener (args[0]);} }; tooltipListener = new XPCOMObject (new int[] {2, 0, 0, 3, 0}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return OnShowTooltip ((int)/*64*/args[0], (int)/*64*/args[1], args[2]);} public long /*int*/ method4 (long /*int*/[] args) {return OnHideTooltip ();} }; domEventListener = new XPCOMObject (new int[] {2, 0, 0, 1}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return HandleEvent (args[0]);} }; badCertListener = new XPCOMObject (new int[] {2, 0, 0, 4}) { public long /*int*/ method0 (long /*int*/[] args) {return QueryInterface (args[0], args[1]);} public long /*int*/ method1 (long /*int*/[] args) {return AddRef ();} public long /*int*/ method2 (long /*int*/[] args) {return Release ();} public long /*int*/ method3 (long /*int*/[] args) {return NotifyCertProblem (args[0], args[1], args[2], args[3]);} }; } void deregisterFunction (BrowserFunction function) { super.deregisterFunction (function); AllFunctions.remove (new Integer (function.index)); } void disposeCOMInterfaces () { if (supports != null) { supports.dispose (); supports = null; } if (weakReference != null) { weakReference.dispose (); weakReference = null; } if (webProgressListener != null) { webProgressListener.dispose (); webProgressListener = null; } if (webProgressListener_17 != null) { webProgressListener_17.dispose (); webProgressListener_17 = null; } if (webBrowserChrome != null) { webBrowserChrome.dispose (); webBrowserChrome = null; } if (webBrowserChromeFocus != null) { webBrowserChromeFocus.dispose (); webBrowserChromeFocus = null; } if (embeddingSiteWindow != null) { embeddingSiteWindow.dispose (); embeddingSiteWindow = null; } if (embeddingSiteWindow_17 != null) { embeddingSiteWindow_17.dispose (); embeddingSiteWindow_17 = null; } if (interfaceRequestor != null) { interfaceRequestor.dispose (); interfaceRequestor = null; } if (supportsWeakReference != null) { supportsWeakReference.dispose (); supportsWeakReference = null; } if (contextMenuListener != null) { contextMenuListener.dispose (); contextMenuListener = null; } if (uriContentListener != null) { uriContentListener.dispose (); uriContentListener = null; } if (tooltipListener != null) { tooltipListener.dispose (); tooltipListener = null; } if (domEventListener != null) { domEventListener.dispose (); domEventListener = null; } if (badCertListener != null) { badCertListener.dispose (); badCertListener = null; } } public boolean execute (String script) { /* * This could be the first content that is set into the browser, so * ensure that the custom subclass that works around Mozilla bug * https://bugzilla.mozilla.org/show_bug.cgi?id=453523 is removed. */ delegate.removeWindowSubclass (); /* * As of mozilla 1.9 executing javascript via the javascript: protocol no * longer happens synchronously. As a result, the result of executing JS * is not returned to the java side when expected by the client. The * workaround is to invoke the javascript handler directly via C++, which is * exposed as of mozilla 1.9. */ long /*int*/[] result = new long /*int*/[1]; if (!IsPre_1_9) { int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); boolean isXULRunner190x = false; nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_SCRIPTSECURITYMANAGER_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager.NS_ISCRIPTSECURITYMANAGER_17_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager.NS_ISCRIPTSECURITYMANAGER_10_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager.NS_ISCRIPTSECURITYMANAGER_191_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager.NS_ISCRIPTSECURITYMANAGER_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { isXULRunner190x = true; } } } } if (rc == XPCOM.NS_OK && result[0] != 0) { nsIScriptSecurityManager securityManager = new nsIScriptSecurityManager (result[0]); result[0] = 0; rc = securityManager.GetSystemPrincipal (result); securityManager.Release (); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIPrincipal principal = new nsIPrincipal (result[0]); result[0] = 0; rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]); result[0] = 0; rc = interfaceRequestor.GetInterface (XPCOM.NS_ISCRIPTGLOBALOBJECT_17_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = interfaceRequestor.GetInterface (XPCOM.NS_ISCRIPTGLOBALOBJECT_10_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = interfaceRequestor.GetInterface (XPCOM.NS_ISCRIPTGLOBALOBJECT_1_9_2_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = interfaceRequestor.GetInterface (XPCOM.NS_ISCRIPTGLOBALOBJECT_1_9_IID, result); } } } interfaceRequestor.Release (); if (rc == XPCOM.NS_OK && result[0] != 0) { long /*int*/ scriptGlobalObject = result[0]; result[0] = 0; if (IsPre_17) { rc = (int/*64*/)XPCOM.nsIScriptGlobalObject_EnsureScriptEnvironment (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */ } else { rc = (int/*64*/)XPCOM.nsIScriptGlobalObject17_EnsureScriptEnvironment (scriptGlobalObject); } if (rc != XPCOM.NS_OK) { new nsISupports (scriptGlobalObject).Release (); } else { long /*int*/ scriptContext; if (IsPre_17) { scriptContext = XPCOM.nsIScriptGlobalObject_GetScriptContext (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */ } else { scriptContext = XPCOM.nsIScriptGlobalObject17_GetScriptContext (scriptGlobalObject); } new nsISupports (scriptGlobalObject).Release (); if (scriptContext != 0) { /* ensure that the received nsIScriptContext implements the expected interface */ nsISupports supports = new nsISupports (scriptContext); rc = supports.QueryInterface (XPCOM.NS_ISCRIPTCONTEXT_17_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = supports.QueryInterface (XPCOM.NS_ISCRIPTCONTEXT_10_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = supports.QueryInterface (XPCOM.NS_ISCRIPTCONTEXT_1_9_2_IID, result); if (!(rc == XPCOM.NS_OK && result[0] != 0)) { result[0] = 0; rc = supports.QueryInterface (XPCOM.NS_ISCRIPTCONTEXT_1_9_IID, result); } } } if (rc == XPCOM.NS_OK && result[0] != 0) { new nsISupports (result[0]).Release (); result[0] = 0; long /*int*/ jsContext; if (IsPre_17) { jsContext = XPCOM.nsIScriptContext_GetNativeContext (scriptContext); } else { jsContext = XPCOM.nsIScriptContext17_GetNativeContext (scriptContext); } if (jsContext != 0) { int length = script.length (); char[] scriptChars = new char[length]; script.getChars(0, length, scriptChars, 0); byte[] urlbytes = MozillaDelegate.wcsToMbcs (null, getUrl (), true); rc = principal.GetJSPrincipals (jsContext, result); long /*int*/ principals = 0; if (rc == XPCOM.NS_OK && result[0] != 0) { principals = result[0]; result[0] = 0; } byte[] jsLibPath = getJSLibPathBytes (); long /*int*/ globalJSObject = XPCOM.JS_GetGlobalObject (jsLibPath, jsContext); if (globalJSObject != 0) { aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_CONTEXTSTACK_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsIJSContextStack.NS_IJSCONTEXTSTACK_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIJSContextStack stack = new nsIJSContextStack (result[0]); result[0] = 0; rc = stack.Push (jsContext); if (rc != XPCOM.NS_OK) { stack.Release (); } else { boolean success = XPCOM.JS_EvaluateUCScriptForPrincipals (jsLibPath, jsContext, globalJSObject, principals, scriptChars, length, urlbytes, 0, isXULRunner190x ? result : null) != 0; result[0] = 0; rc = stack.Pop (result); stack.Release (); // should principals be Release()d too? principal.Release (); serviceManager.Release (); return success; } } } } } } } } principal.Release (); } } serviceManager.Release (); } /* fall back to the pre-1.9 approach */ String url = PREFIX_JAVASCRIPT + script + ";void(0);"; //$NON-NLS-1$ int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); char[] arg = url.toCharArray (); char[] c = new char[arg.length+1]; System.arraycopy (arg, 0, c, 0, arg.length); rc = webNavigation.LoadURI (c, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0); webNavigation.Release (); return rc == XPCOM.NS_OK; } static Browser findBrowser (long /*int*/ handle) { return MozillaDelegate.findBrowser (handle); } static Browser getBrowser (long /*int*/ aDOMWindow) { long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) Mozilla.error (rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsIWindowWatcher.NS_IWINDOWWATCHER_IID, result); if (rc != XPCOM.NS_OK) Mozilla.error(rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE); serviceManager.Release (); nsIWindowWatcher windowWatcher = new nsIWindowWatcher (result[0]); result[0] = 0; /* the chrome will only be answered for the top-level nsIDOMWindow */ nsIDOMWindow window = new nsIDOMWindow (aDOMWindow); rc = window.GetTop (result); if (rc != XPCOM.NS_OK) Mozilla.error (rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE); long /*int*/ topDOMWindow = result[0]; result[0] = 0; rc = windowWatcher.GetChromeForWindow (topDOMWindow, result); if (rc != XPCOM.NS_OK) Mozilla.error (rc); new nsISupports (topDOMWindow).Release (); windowWatcher.Release (); if (result[0] == 0) return null; /* the parent chrome is disconnected */ nsIWebBrowserChrome webBrowserChrome = new nsIWebBrowserChrome (result[0]); result[0] = 0; rc = webBrowserChrome.QueryInterface (IsPre_17 ? nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID : nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_17_IID, result); if (rc != XPCOM.NS_OK) Mozilla.error (rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE); webBrowserChrome.Release (); nsIEmbeddingSiteWindow embeddingSiteWindow = new nsIEmbeddingSiteWindow (result[0]); result[0] = 0; IsGettingSiteWindow = true; rc = embeddingSiteWindow.GetSiteWindow (result); IsGettingSiteWindow = false; if (rc != XPCOM.NS_OK) Mozilla.error (rc); if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE); embeddingSiteWindow.Release (); return findBrowser (result[0]); } public boolean forward () { htmlBytes = null; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); rc = webNavigation.GoForward (); webNavigation.Release (); return rc == XPCOM.NS_OK; } public String getBrowserType () { return "mozilla"; //$NON-NLS-1$ } static byte[] getJSLibPathBytes () { if (jsLibPathBytes == null) { String[] names = IsPre_4 ? new String[] {MozillaDelegate.getJSLibraryName_Pre4 ()} : MozillaDelegate.getJSLibraryNames (); for (int i = 0; i < names.length; i++) { File file = new File (getMozillaPath (), names[i]); if (file.exists ()) { String pathString = file.getAbsolutePath () + '\0'; try { jsLibPathBytes = pathString.getBytes ("UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { jsLibPathBytes = pathString.getBytes (); } break; } } } return jsLibPathBytes; } static String getMozillaPath () { if (LocationProvider != null) return LocationProvider.mozillaPath; if (!Initialized) return ""; long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DIRECTORYSERVICE_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (buffer, XPCOM.NS_IDIRECTORYSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); serviceManager.Release(); nsISupports directoryService = new nsISupports (result[0]); result[0] = 0; rc = directoryService.QueryInterface (nsIProperties.NS_IPROPERTIES_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); directoryService.Release (); nsIProperties properties = new nsIProperties (result[0]); result[0] = 0; buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_GRE_DIR, true); rc = properties.Get (buffer, IsPre_17 ? nsIFile.NS_IFILE_IID : nsIFile.NS_IFILE_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); properties.Release (); nsIFile mozillaDir = new nsIFile (result[0]); result[0] = 0; long /*int*/ path = XPCOM.nsEmbedString_new (); rc = mozillaDir.GetPath (path); if (rc != XPCOM.NS_OK) error (rc); int length = XPCOM.nsEmbedString_Length (path); long /*int*/ ptr = XPCOM.nsEmbedString_get (path); char[] chars = new char[length]; XPCOM.memmove (chars, ptr, length * 2); XPCOM.nsEmbedString_delete (path); mozillaDir.Release (); return new String (chars) + SEPARATOR_OS; } int getNextFunctionIndex () { return NextJSFunctionIndex++; } public String getText () { long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.GetContentDOMWindow (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMWindow window = new nsIDOMWindow (result[0]); result[0] = 0; rc = window.GetDocument (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); window.Release (); long /*int*/ document = result[0]; result[0] = 0; rc = XPCOM.NS_GetComponentManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIComponentManager componentManager = new nsIComponentManager (result[0]); result[0] = 0; byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOMSERIALIZER_CONTRACTID, true); char[] chars = null; rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIDOMSerializer_1_7.NS_IDOMSERIALIZER_IID, result); if (rc == XPCOM.NS_OK) { /* mozilla >= 1.7 */ if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMSerializer_1_7 serializer = new nsIDOMSerializer_1_7 (result[0]); result[0] = 0; long /*int*/ string = XPCOM.nsEmbedString_new (); rc = serializer.SerializeToString (document, string); serializer.Release (); int length = XPCOM.nsEmbedString_Length (string); long /*int*/ buffer = XPCOM.nsEmbedString_get (string); chars = new char[length]; XPCOM.memmove (chars, buffer, length * 2); XPCOM.nsEmbedString_delete (string); } else { /* mozilla < 1.7 */ rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIDOMSerializer.NS_IDOMSERIALIZER_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMSerializer serializer = new nsIDOMSerializer (result[0]); result[0] = 0; rc = serializer.SerializeToString (document, result); serializer.Release (); int length = XPCOM.strlen_PRUnichar (result[0]); chars = new char[length]; XPCOM.memmove (chars, result[0], length * 2); } componentManager.Release (); new nsISupports (document).Release (); return new String (chars); } public String getUrl () { long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); long /*int*/[] aCurrentURI = new long /*int*/[1]; rc = webNavigation.GetCurrentURI (aCurrentURI); if (rc != XPCOM.NS_OK) error (rc); webNavigation.Release (); byte[] dest = null; if (aCurrentURI[0] != 0) { nsIURI uri = new nsIURI (aCurrentURI[0]); long /*int*/ aSpec = XPCOM.nsEmbedCString_new (); rc = uri.GetSpec (aSpec); if (rc != XPCOM.NS_OK) error (rc); int length = XPCOM.nsEmbedCString_Length (aSpec); long /*int*/ buffer = XPCOM.nsEmbedCString_get (aSpec); dest = new byte[length]; XPCOM.memmove (dest, buffer, length); XPCOM.nsEmbedCString_delete (aSpec); uri.Release (); } if (dest == null) return ""; //$NON-NLS-1$ String location = new String (dest); /* * If the URI indicates that the page is being rendered from memory * (via setText()) then set it to about:blank to be consistent with IE. */ if (location.equals (URI_FILEROOT)) { location = ABOUT_BLANK; } else { int length = URI_FILEROOT.length (); if (location.startsWith (URI_FILEROOT) && location.charAt (length) == '#') { location = ABOUT_BLANK + location.substring (length); } } return location; } public Object getWebBrowser () { if ((browser.getStyle () & SWT.MOZILLA) == 0) return null; if (webBrowserObject != null) return webBrowserObject; try { Class clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$ Method method = clazz.getMethod ("getInstance", new Class[0]); //$NON-NLS-1$ Object mozilla = method.invoke (null, new Object[0]); method = clazz.getMethod ("wrapXPCOMObject", new Class[] {Long.TYPE, String.class}); //$NON-NLS-1$ webBrowserObject = method.invoke (mozilla, new Object[] {new Long (webBrowser.getAddress ()), !IsPre_4 ? nsIWebBrowser.NS_IWEBBROWSER_10_IID_STR : nsIWebBrowser.NS_IWEBBROWSER_IID_STR}); /* * The following AddRef() is needed to offset the automatic Release() that * will be performed by JavaXPCOM when webBrowserObject is finalized. */ webBrowser.AddRef (); return webBrowserObject; } catch (ClassNotFoundException e) { } catch (NoSuchMethodException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } return null; } static String InitDiscoverXULRunner () { /* * Up to three XULRunner detection attempts will be made: * * 1. A XULRunner with 1.8.1.2 <= version < 2.0, and with "abi" property matching * the current runtime. Note that XULRunner registrations began including abi * info as of version 1.9.x, so older versions than this will not be returned. * 2. A XULRunner with 1.8.1.2 <= version < 2.0. XULRunner 1.8.1.2 is the oldest * release that enables the Browser to expose its JavaXPCOM interfaces to clients. * 3. A XULRunner with 1.8.0.1 <= version < 2.0. */ GREVersionRange range = new GREVersionRange (); byte[] bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER, true); long /*int*/ lower = C.malloc (bytes.length); C.memmove (lower, bytes, bytes.length); range.lower = lower; range.lowerInclusive = LowerRangeInclusive; bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_UPPER, true); long /*int*/ upper = C.malloc (bytes.length); C.memmove (upper, bytes, bytes.length); range.upper = upper; range.upperInclusive = UpperRangeInclusive; GREProperty property = new GREProperty (); bytes = MozillaDelegate.wcsToMbcs (null, PROPERTY_ABI, true); long /*int*/ name = C.malloc (bytes.length); C.memmove (name, bytes, bytes.length); property.property = name; bytes = MozillaDelegate.wcsToMbcs (null, Arch () + GCC3, true); long /*int*/ value = C.malloc (bytes.length); C.memmove (value, bytes, bytes.length); property.value = value; int length = XPCOMInit.PATH_MAX; long /*int*/ greBuffer = C.malloc (length); int rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, property, 1, greBuffer, length); if (rc != XPCOM.NS_OK) { /* Fall back to attempt #2 */ rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, property, 0, greBuffer, length); /* note: propertiesLength is 0 */ if (rc != XPCOM.NS_OK) { /* Fall back to attempt #3 */ C.free (lower); bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER_FALLBACK, true); lower = C.malloc (bytes.length); C.memmove (lower, bytes, bytes.length); range.lower = lower; rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, property, 0, greBuffer, length); /* note: propertiesLength is 0 */ } } C.free (value); C.free (name); C.free (lower); C.free (upper); String result = null; if (rc == XPCOM.NS_OK) { /* indicates that a XULRunner was found */ length = C.strlen (greBuffer); bytes = new byte[length]; C.memmove (bytes, greBuffer, length); result = new String (MozillaDelegate.mbcsToWcs (null, bytes)); } else { result = ""; //$NON-NLS-1$ } C.free (greBuffer); return result; } void initExternal (String profilePath) { File componentsDir = new File (profilePath, AppFileLocProvider.COMPONENTS_DIR); java.io.InputStream is = Library.class.getResourceAsStream ("/external.xpt"); //$NON-NLS-1$ if (is != null) { if (!componentsDir.exists ()) { componentsDir.mkdirs (); } int read; byte [] buffer = new byte [4096]; File file = new File (componentsDir, "external.xpt"); //$NON-NLS-1$ try { FileOutputStream os = new FileOutputStream (file); while ((read = is.read (buffer)) != -1) { os.write(buffer, 0, read); } os.close (); is.close (); } catch (FileNotFoundException e) { } catch (IOException e) { } } } void initFactories (nsIServiceManager serviceManager, nsIComponentManager componentManager, boolean isXULRunner) { long /*int*/[] result = new long /*int*/[1]; int rc = componentManager.QueryInterface (nsIComponentRegistrar.NS_ICOMPONENTREGISTRAR_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIComponentRegistrar componentRegistrar = new nsIComponentRegistrar (result[0]); result[0] = 0; if (IsPre_17) { componentRegistrar.AutoRegister (0); /* detect the External component */ } PromptService2Factory factory = new PromptService2Factory (); factory.AddRef (); byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PROMPTSERVICE_CONTRACTID, true); byte[] aClassName = MozillaDelegate.wcsToMbcs (null, "swtPromptService", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_PROMPTSERVICE_CID, aClassName, aContractID, factory.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (!IsPre_4) { aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PROMPTER_CONTRACTID, true); aClassName = MozillaDelegate.wcsToMbcs (null, "swtPrompter", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_PROMPTER_CID, aClassName, aContractID, factory.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_AUTHPROMPTER_CONTRACTID, true); aClassName = MozillaDelegate.wcsToMbcs (null, "swtAuthPrompter", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_AUTHPROMPTER_CID, aClassName, aContractID, factory.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } } factory.Release(); ExternalFactory externalFactory = new ExternalFactory (); externalFactory.AddRef (); aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.EXTERNAL_CONTRACTID, true); aClassName = MozillaDelegate.wcsToMbcs (null, "External", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.EXTERNAL_CID, aClassName, aContractID, externalFactory.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } externalFactory.Release (); rc = serviceManager.GetService (XPCOM.NS_CATEGORYMANAGER_CID, nsICategoryManager.NS_ICATEGORYMANAGER_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsICategoryManager categoryManager = new nsICategoryManager (result[0]); result[0] = 0; byte[] entry = MozillaDelegate.wcsToMbcs (null, "external", true); //$NON-NLS-1$ /* register for mozilla versions <= 3.6.x */ byte[] category = MozillaDelegate.wcsToMbcs (null, "JavaScript global property", true); //$NON-NLS-1$ rc = categoryManager.AddCategoryEntry (category, entry, aContractID, 0, 1, result); result[0] = 0; /* register for mozilla versions >= 3.6.x */ category = MozillaDelegate.wcsToMbcs (null, "JavaScript-global-property", true); //$NON-NLS-1$ rc = categoryManager.AddCategoryEntry (category, entry, aContractID, 0, 1, result); result[0] = 0; categoryManager.Release (); /* * This Download factory will be used if the GRE version is < 1.8. * If the GRE version is 1.8.x then the Download factory that is registered later for * contract "Transfer" will be used. * If the GRE version is >= 1.9 then no Download factory is registered because this * functionality is provided by the GRE. */ if (IsPre_4) { DownloadFactory downloadFactory = new DownloadFactory (); downloadFactory.AddRef (); aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_DOWNLOAD_CONTRACTID, true); aClassName = MozillaDelegate.wcsToMbcs (null, "swtDownload", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_DOWNLOAD_CID, aClassName, aContractID, downloadFactory.getAddress ()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } downloadFactory.Release (); } FilePickerFactory pickerFactory = new FilePickerFactory (); pickerFactory.AddRef (); aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_FILEPICKER_CONTRACTID, true); aClassName = MozillaDelegate.wcsToMbcs (null, "swtFilePicker", true); //$NON-NLS-1$ rc = componentRegistrar.RegisterFactory (XPCOM.NS_FILEPICKER_CID, aClassName, aContractID, pickerFactory.getAddress ()); /* a failure here is fine, it likely indicates that the OS has provided a default implementation */ pickerFactory.Release (); componentRegistrar.Release (); } void initJavaXPCOM (String mozillaPath) { try { Class clazz = Class.forName ("org.mozilla.xpcom.Mozilla"); //$NON-NLS-1$ Method method = clazz.getMethod ("getInstance", new Class[0]); //$NON-NLS-1$ Object mozilla = method.invoke (null, new Object[0]); method = clazz.getMethod ("getComponentManager", new Class[0]); //$NON-NLS-1$ try { method.invoke (mozilla, new Object[0]); } catch (InvocationTargetException e) { /* indicates that JavaXPCOM has not been initialized yet */ Class fileClass = Class.forName ("java.io.File"); //$NON-NLS-1$ method = clazz.getMethod ("initialize", new Class[] {fileClass}); //$NON-NLS-1$ Constructor constructor = fileClass.getDeclaredConstructor (new Class[] {String.class}); Object argument = constructor.newInstance (new Object[] {mozillaPath}); method.invoke (mozilla, new Object[] {argument}); } } catch (ClassNotFoundException e) { /* JavaXPCOM is not on the classpath */ } catch (NoSuchMethodException e) { /* the JavaXPCOM on the classpath does not implement initialize() */ } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } catch (InstantiationException e) { } } String initMozilla (String mozillaPath) { /* attempt to use the GRE pointed at by MOZILLA_FIVE_HOME */ long /*int*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, MOZILLA_FIVE_HOME, true)); if (ptr != 0) { int length = C.strlen (ptr); byte[] buffer = new byte[length]; C.memmove (buffer, ptr, length); mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, buffer)); /* ensure that client-supplied path is using correct separators */ if (SEPARATOR_OS == '/') { mozillaPath = mozillaPath.replace ('\\', SEPARATOR_OS); } else { mozillaPath = mozillaPath.replace ('/', SEPARATOR_OS); } } else { browser.dispose (); SWT.error (SWT.ERROR_NO_HANDLES, null, " [Unknown Mozilla path (MOZILLA_FIVE_HOME not set)]"); //$NON-NLS-1$ } if (Device.DEBUG) System.out.println ("Mozilla path: " + mozillaPath); //$NON-NLS-1$ /* * Note. Embedding a Mozilla GTK1.2 causes a crash. The workaround * is to check the version of GTK used by Mozilla by looking for * the libwidget_gtk.so library used by Mozilla GTK1.2. Mozilla GTK2 * uses the libwidget_gtk2.so library. */ if (Compatibility.fileExists (mozillaPath, "components/libwidget_gtk.so")) { //$NON-NLS-1$ browser.dispose (); SWT.error (SWT.ERROR_NO_HANDLES, null, " [Mozilla GTK2 required (GTK1.2 detected)]"); //$NON-NLS-1$ } try { Library.loadLibrary ("swt-mozilla"); //$NON-NLS-1$ } catch (UnsatisfiedLinkError e) { try { /* * The initial loadLibrary attempt may have failed as a result of the user's * system not having libstdc++.so.6 installed, so try to load the alternate * swt mozilla library that depends on libswtc++.so.5 instead. */ Library.loadLibrary ("swt-mozilla-gcc3"); //$NON-NLS-1$ } catch (UnsatisfiedLinkError ex) { browser.dispose (); /* * Print the error from the first failed attempt since at this point it's * known that the failure was not due to the libstdc++.so.6 dependency. */ SWT.error (SWT.ERROR_NO_HANDLES, e, " [MOZILLA_FIVE_HOME='" + mozillaPath + "']"); //$NON-NLS-1$ //$NON-NLS-2$ } } return mozillaPath; } void initXPCOM (String mozillaPath, boolean isXULRunner) { long /*int*/[] result = new long /*int*/[1]; nsEmbedString pathString = new nsEmbedString (mozillaPath); int rc = XPCOM.NS_NewLocalFile (pathString.getAddress (), 1, result); pathString.dispose (); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_ERROR_NULL_POINTER); } nsIFile localFile = new nsIFile (result[0]); result[0] = 0; if (isXULRunner) { int size = XPCOM.nsDynamicFunctionLoad_sizeof (); /* alloc memory for two structs, the second is empty to signify the end of the list */ long /*int*/ ptr = C.malloc (size * 2); C.memset (ptr, 0, size * 2); nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad (); /* * Attempt to load the XRE_InitEmbedding2 function first, which is present in * mozilla versions > 3.x. */ byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_InitEmbedding2", true); //$NON-NLS-1$ functionLoad.functionName = C.malloc (bytes.length); C.memmove (functionLoad.functionName, bytes, bytes.length); functionLoad.function = C.malloc (C.PTR_SIZEOF); C.memmove (functionLoad.function, new long /*int*/[] {0} , C.PTR_SIZEOF); XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); rc = XPCOM.XPCOMGlueLoadXULFunctions (ptr); if (rc == XPCOM.NS_OK) { /* > 3.x */ result[0] = 0; rc = localFile.QueryInterface(nsIFile.NS_IFILE_17_IID, result); if (rc == XPCOM.NS_OK) { /* 17.x */ nsISupports.IsXULRunner17 = true; } else { /* 10.x */ rc = localFile.QueryInterface (nsILocalFile.NS_ILOCALFILE_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } IsPre_17 = true; nsISupports.IsXULRunner10 = true; } if (result[0] != 0) new nsISupports (result[0]).Release(); result[0] = 0; } else { /* * XRE_InitEmbedding2 was not found, so fall back to XRE_InitEmbedding, which is * present in older mozilla versions. */ C.free (functionLoad.functionName); bytes = MozillaDelegate.wcsToMbcs (null, "XRE_InitEmbedding", true); //$NON-NLS-1$ functionLoad.functionName = C.malloc (bytes.length); C.memmove (functionLoad.functionName, bytes, bytes.length); XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); rc = XPCOM.XPCOMGlueLoadXULFunctions (ptr); IsPre_4 = IsPre_17 = true; } C.memmove (result, functionLoad.function, C.PTR_SIZEOF); long /*int*/ functionPtr = result[0]; result[0] = 0; C.free (functionLoad.function); C.free (functionLoad.functionName); C.free (ptr); if (functionPtr == 0) { browser.dispose (); error (XPCOM.NS_ERROR_NULL_POINTER); } if (nsISupports.IsXULRunner17 && !MozillaDelegate.supportsXULRunner17 ()) { browser.dispose (); SWT.error (SWT.ERROR_NO_HANDLES, null, " [XULRunner 17 is not supported on this platform]"); //$NON-NLS-1$ } if (IsPre_4) { rc = XPCOM.Call (functionPtr, localFile.getAddress (), localFile.getAddress (), LocationProvider.getAddress (), 0, 0); } else { rc = XPCOM.Call (functionPtr, localFile.getAddress (), localFile.getAddress (), LocationProvider.getAddress ()); } if (rc == XPCOM.NS_OK) { System.setProperty (XULRUNNER_PATH, mozillaPath); } } else { IsPre_4 = IsPre_17 = true; rc = XPCOM.NS_InitXPCOM2 (0, localFile.getAddress(), LocationProvider.getAddress ()); } localFile.Release (); if (rc != XPCOM.NS_OK) { browser.dispose (); SWT.error (SWT.ERROR_NO_HANDLES, null, " [MOZILLA_FIVE_HOME may not point at an embeddable GRE] [NS_InitEmbedding " + mozillaPath + " error " + rc + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } System.setProperty (GRE_INITIALIZED, TRUE); } void initPreferences (nsIServiceManager serviceManager, nsIComponentManager componentManager) { long /*int*/[] result = new long /*int*/[1]; /* * As a result of using a common profile the user cannot change their locale * and charset. The fix for this is to set mozilla's locale and charset * preference values according to the user's current locale and charset. */ byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFSERVICE_CONTRACTID, true); int rc = serviceManager.GetServiceByContractID (aContractID, nsIPrefService.NS_IPREFSERVICE_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIPrefService prefService = new nsIPrefService (result[0]); result[0] = 0; byte[] buffer = new byte[1]; rc = prefService.GetBranch (buffer, result); /* empty buffer denotes root preference level */ prefService.Release (); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIPrefBranch prefBranch = new nsIPrefBranch (result[0]); result[0] = 0; /* get Mozilla's current locale preference value */ String prefLocales = null; nsIPrefLocalizedString localizedString = null; buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_LANGUAGES, true); rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); /* * Feature of Debian. For some reason attempting to query for the current locale * preference fails on Debian. The workaround for this is to assume a value of * "en-us,en" since this is typically the default value when mozilla is used without * a profile. */ if (rc != XPCOM.NS_OK) { prefLocales = "en-us,en" + TOKENIZER_LOCALE; //$NON-NLS-1$ } else { if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } localizedString = new nsIPrefLocalizedString (result[0]); result[0] = 0; rc = localizedString.ToString (result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } int length = XPCOM.strlen_PRUnichar (result[0]); char[] dest = new char[length]; XPCOM.memmove (dest, result[0], length * 2); prefLocales = new String (dest) + TOKENIZER_LOCALE; } result[0] = 0; /* * construct the new locale preference value by prepending the * user's current locale and language to the original value */ Locale locale = Locale.getDefault (); String language = locale.getLanguage (); String country = locale.getCountry (); StringBuffer stringBuffer = new StringBuffer (language); stringBuffer.append (SEPARATOR_LOCALE); stringBuffer.append (country.toLowerCase ()); stringBuffer.append (TOKENIZER_LOCALE); stringBuffer.append (language); stringBuffer.append (TOKENIZER_LOCALE); String newLocales = stringBuffer.toString (); int start, end = -1; do { start = end + 1; end = prefLocales.indexOf (TOKENIZER_LOCALE, start); String token; if (end == -1) { token = prefLocales.substring (start); } else { token = prefLocales.substring (start, end); } if (token.length () > 0) { token = (token + TOKENIZER_LOCALE).trim (); /* ensure that duplicate locale values are not added */ if (newLocales.indexOf (token) == -1) { stringBuffer.append (token); } } } while (end != -1); newLocales = stringBuffer.toString (); if (!newLocales.equals (prefLocales)) { /* write the new locale value */ newLocales = newLocales.substring (0, newLocales.length () - TOKENIZER_LOCALE.length ()); /* remove trailing tokenizer */ int length = newLocales.length (); char[] charBuffer = new char[length + 1]; newLocales.getChars (0, length, charBuffer, 0); if (localizedString == null) { byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } localizedString = new nsIPrefLocalizedString (result[0]); result[0] = 0; } localizedString.SetDataWithLength (length, charBuffer); rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress()); } if (localizedString != null) { localizedString.Release (); localizedString = null; } /* get Mozilla's current charset preference value */ String prefCharset = null; buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_CHARSET, true); rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); /* * Feature of Debian. For some reason attempting to query for the current charset * preference fails on Debian. The workaround for this is to assume a value of * "ISO-8859-1" since this is typically the default value when mozilla is used * without a profile. */ if (rc != XPCOM.NS_OK) { prefCharset = "ISO-8859-1"; //$NON-NLS-1$ } else { if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } localizedString = new nsIPrefLocalizedString (result[0]); result[0] = 0; rc = localizedString.ToString (result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } int length = XPCOM.strlen_PRUnichar (result[0]); char[] dest = new char[length]; XPCOM.memmove (dest, result[0], length * 2); prefCharset = new String (dest); } result[0] = 0; String newCharset = System.getProperty ("file.encoding"); // $NON-NLS-1$ if (!newCharset.equals (prefCharset)) { /* write the new charset value */ int length = newCharset.length (); char[] charBuffer = new char[length + 1]; newCharset.getChars (0, length, charBuffer, 0); if (localizedString == null) { byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } localizedString = new nsIPrefLocalizedString (result[0]); result[0] = 0; } localizedString.SetDataWithLength (length, charBuffer); rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); } if (localizedString != null) localizedString.Release (); /* * Check for proxy values set as documented java properties and update mozilla's * preferences with these values if needed. */ String proxyHost = System.getProperty (PROPERTY_PROXYHOST); int port = -1; int propertyValue = Integer.getInteger (PROPERTY_PROXYPORT, -1).intValue (); if (0 <= propertyValue && propertyValue <= MAX_PORT) port = propertyValue; if (proxyHost != null) { byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_PREFLOCALIZEDSTRING_CONTRACTID, true); rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); localizedString = new nsIPrefLocalizedString (result[0]); result[0] = 0; int length = proxyHost.length (); char[] charBuffer = new char[length]; proxyHost.getChars (0, length, charBuffer, 0); rc = localizedString.SetDataWithLength (length, charBuffer); if (rc != XPCOM.NS_OK) error (rc); buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_FTP, true); rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIPrefLocalizedString value = new nsIPrefLocalizedString (result[0]); result[0] = 0; rc = value.ToString (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); length = XPCOM.strlen_PRUnichar (result[0]); char[] dest = new char[length]; XPCOM.memmove (dest, result[0], length * 2); oldProxyHostFTP = new String (dest); } else { /* value is default */ oldProxyHostFTP = DEFAULTVALUE_STRING; } result[0] = 0; rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_HTTP, true); rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIPrefLocalizedString value = new nsIPrefLocalizedString (result[0]); result[0] = 0; rc = value.ToString (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); length = XPCOM.strlen_PRUnichar (result[0]); char[] dest = new char[length]; XPCOM.memmove (dest, result[0], length * 2); oldProxyHostHTTP = new String (dest); } else { /* value is default */ oldProxyHostHTTP = DEFAULTVALUE_STRING; } result[0] = 0; rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYHOST_SSL, true); rc = prefBranch.GetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIPrefLocalizedString value = new nsIPrefLocalizedString (result[0]); result[0] = 0; rc = value.ToString (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); length = XPCOM.strlen_PRUnichar (result[0]); char[] dest = new char[length]; XPCOM.memmove (dest, result[0], length * 2); oldProxyHostSSL = new String (dest); } else { /* value is default */ oldProxyHostSSL = DEFAULTVALUE_STRING; } result[0] = 0; rc = prefBranch.SetComplexValue (buffer, nsIPrefLocalizedString.NS_IPREFLOCALIZEDSTRING_IID, localizedString.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); localizedString.Release (); } int[] intResult = new int[1]; /* C long*/ if (port != -1) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_FTP, true); rc = prefBranch.GetIntPref (buffer, intResult); if (rc != XPCOM.NS_OK) error (rc); oldProxyPortFTP = intResult[0]; intResult[0] = 0; rc = prefBranch.SetIntPref (buffer, port); if (rc != XPCOM.NS_OK) error (rc); buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_HTTP, true); rc = prefBranch.GetIntPref (buffer, intResult); if (rc != XPCOM.NS_OK) error (rc); oldProxyPortHTTP = intResult[0]; intResult[0] = 0; rc = prefBranch.SetIntPref (buffer, port); if (rc != XPCOM.NS_OK) error (rc); buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYPORT_SSL, true); rc = prefBranch.GetIntPref (buffer, intResult); if (rc != XPCOM.NS_OK) error (rc); oldProxyPortSSL = intResult[0]; intResult[0] = 0; rc = prefBranch.SetIntPref (buffer, port); if (rc != XPCOM.NS_OK) error (rc); } if (proxyHost != null || port != -1) { buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_PROXYTYPE, true); rc = prefBranch.GetIntPref (buffer, intResult); if (rc != XPCOM.NS_OK) error (rc); oldProxyType = intResult[0]; intResult[0] = 0; rc = prefBranch.SetIntPref (buffer, 1); if (rc != XPCOM.NS_OK) error (rc); } /* * Ensure that windows that are shown during page loads are not blocked. Firefox may * try to block these by default since such windows are often unwelcome, but this * assumption should not be made in the Browser's context. Since the Browser client * is responsible for creating the new Browser and Shell in an OpenWindowListener, * they should decide whether the new window is unwelcome or not and act accordingly. */ buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEOPENDURINGLOAD, true); rc = prefBranch.SetBoolPref (buffer, 0); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } /* Ensure that the status text can be set through means like javascript */ buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEWINDOWSTATUSCHANGE, true); rc = prefBranch.SetBoolPref (buffer, 0); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } /* Ensure that the status line can be hidden when opening a window from javascript */ buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_DISABLEOPENWINDOWSTATUSHIDE, true); rc = prefBranch.SetBoolPref (buffer, 0); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } /* Ensure that javascript execution is enabled since this is the Browser's default behaviour */ buffer = MozillaDelegate.wcsToMbcs (null, PREFERENCE_JAVASCRIPTENABLED, true); rc = prefBranch.SetBoolPref (buffer, 1); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } prefBranch.Release (); } void initProfile (nsIServiceManager serviceManager, boolean isXULRunner) { long /*int*/[] result = new long /*int*/[1]; byte[] buffer = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_OBSERVER_CONTRACTID, true); int rc = serviceManager.GetServiceByContractID (buffer, nsIObserverService.NS_IOBSERVERSERVICE_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIObserverService observerService = new nsIObserverService (result[0]); result[0] = 0; buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_DO_CHANGE, true); int length = STARTUP.length (); char[] chars = new char [length + 1]; STARTUP.getChars (0, length, chars, 0); rc = observerService.NotifyObservers (0, buffer, chars); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } buffer = MozillaDelegate.wcsToMbcs (null, PROFILE_AFTER_CHANGE, true); rc = observerService.NotifyObservers (0, buffer, chars); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } observerService.Release (); if (isXULRunner) { int size = XPCOM.nsDynamicFunctionLoad_sizeof (); /* alloc memory for two structs, the second is empty to signify the end of the list */ long /*int*/ ptr = C.malloc (size * 2); C.memset (ptr, 0, size * 2); nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad (); byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_NotifyProfile", true); //$NON-NLS-1$ functionLoad.functionName = C.malloc (bytes.length); C.memmove (functionLoad.functionName, bytes, bytes.length); functionLoad.function = C.malloc (C.PTR_SIZEOF); C.memmove (functionLoad.function, new long /*int*/[] {0} , C.PTR_SIZEOF); XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); XPCOM.XPCOMGlueLoadXULFunctions (ptr); C.memmove (result, functionLoad.function, C.PTR_SIZEOF); long /*int*/ functionPtr = result[0]; result[0] = 0; C.free (functionLoad.function); C.free (functionLoad.functionName); C.free (ptr); /* functionPtr == 0 for xulrunner < 1.9 */ if (functionPtr != 0) { rc = XPCOM.Call (functionPtr); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } } } } void initSpinup (nsIComponentManager componentManager) { if (MozillaDelegate.needsSpinup ()) { long /*int*/[] result = new long /*int*/[1]; /* nsIAppShell is discontinued as of xulrunner 1.9, so do not fail if it is not found */ int rc = componentManager.CreateInstance (XPCOM.NS_APPSHELL_CID, 0, nsIAppShell.NS_IAPPSHELL_IID, result); if (rc != XPCOM.NS_ERROR_NO_INTERFACE) { if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } AppShell = new nsIAppShell (result[0]); result[0] = 0; rc = AppShell.Create (0, null); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } rc = AppShell.Spinup (); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } } } } void initWebBrowserWindows () { int rc = webBrowser.SetContainerWindow (webBrowserChrome.getAddress()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } long /*int*/[] result = new long /*int*/[1]; rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_10_IID, result); if (rc != XPCOM.NS_OK) { rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_ERROR_NO_INTERFACE); } nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); result[0] = 0; Rectangle rect = browser.getClientArea (); if (rect.isEmpty ()) { rect.width = 1; rect.height = 1; } embedHandle = delegate.getHandle (); rc = baseWindow.InitWindow (embedHandle, 0, 0, 0, rect.width, rect.height); if (rc != XPCOM.NS_OK) { browser.dispose (); error (XPCOM.NS_ERROR_FAILURE); } rc = delegate.createBaseWindow (baseWindow); if (rc != XPCOM.NS_OK) { browser.dispose (); error (XPCOM.NS_ERROR_FAILURE); } rc = baseWindow.SetVisibility (1); if (rc != XPCOM.NS_OK) { browser.dispose (); error (XPCOM.NS_ERROR_FAILURE); } baseWindow.Release (); } void initWindowCreator (nsIServiceManager serviceManager) { WindowCreator = new WindowCreator2 (); WindowCreator.AddRef (); long /*int*/[] result = new long /*int*/[1]; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WINDOWWATCHER_CONTRACTID, true); int rc = serviceManager.GetServiceByContractID (aContractID, nsIWindowWatcher.NS_IWINDOWWATCHER_IID, result); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } if (result[0] == 0) { browser.dispose (); error (XPCOM.NS_NOINTERFACE); } nsIWindowWatcher windowWatcher = new nsIWindowWatcher (result[0]); result[0] = 0; rc = windowWatcher.SetWindowCreator (WindowCreator.getAddress()); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } windowWatcher.Release (); } String initXULRunner (String mozillaPath) { if (Device.DEBUG) System.out.println ("XULRunner path: " + mozillaPath); //$NON-NLS-1$ try { Library.loadLibrary ("swt-xulrunner"); //$NON-NLS-1$ } catch (UnsatisfiedLinkError e) { SWT.error (SWT.ERROR_NO_HANDLES, e); } /* * Remove the trailing xpcom lib name from mozillaPath because the * Mozilla.initialize and NS_InitXPCOM2 invocations require a directory name only. */ String mozillaDirPath = mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS)); MozillaDelegate.loadAdditionalLibraries (mozillaDirPath); byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true); int rc = XPCOM.XPCOMGlueStartup (path); if (rc != XPCOM.NS_OK) { browser.dispose (); error (rc); } XPCOMWasGlued = true; return mozillaDirPath; } public boolean isBackEnabled () { long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); int[] aCanGoBack = new int[1]; /* PRBool */ rc = webNavigation.GetCanGoBack (aCanGoBack); webNavigation.Release (); return aCanGoBack[0] != 0; } public boolean isForwardEnabled () { long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); int[] aCanGoForward = new int[1]; /* PRBool */ rc = webNavigation.GetCanGoForward (aCanGoForward); webNavigation.Release (); return aCanGoForward[0] != 0; } static String error (int code) { throw new SWTError ("XPCOM error 0x" + Integer.toHexString(code)); //$NON-NLS-1$ } void onDispose (Display display) { /* invoke onbeforeunload handlers */ if (!browser.isClosing && !browser.isDisposed()) { LocationListener[] oldLocationListeners = locationListeners; locationListeners = new LocationListener[0]; ignoreAllMessages = true; execute ("window.location.replace('about:blank');"); //$NON-NLS-1$ ignoreAllMessages = false; locationListeners = oldLocationListeners; } if (badCertRequest != 0) { new nsISupports (badCertRequest).Release (); } int rc = webBrowser.RemoveWebBrowserListener (weakReference.getAddress (), IsPre_17 ? nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID : nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_17_IID); if (rc != XPCOM.NS_OK) error (rc); rc = webBrowser.SetParentURIContentListener (0); if (rc != XPCOM.NS_OK) error (rc); rc = webBrowser.SetContainerWindow (0); if (rc != XPCOM.NS_OK) error (rc); unhookDOMListeners (); long /*int*/[] result = new long /*int*/[1]; rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_10_IID, result); if (rc != XPCOM.NS_OK) { rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); if (rc != XPCOM.NS_OK) error (rc); } if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); rc = baseWindow.Destroy (); if (rc != XPCOM.NS_OK) error (rc); baseWindow.Release (); Release (); webBrowser.Release (); webBrowser = null; webBrowserObject = null; lastNavigateURL = null; htmlBytes = null; listener = null; if (tip != null && !tip.isDisposed ()) tip.dispose (); tip = null; location = size = null; Enumeration elements = unhookedDOMWindows.elements (); while (elements.hasMoreElements ()) { LONG ptrObject = (LONG)elements.nextElement (); new nsISupports (ptrObject.value).Release (); } unhookedDOMWindows = null; elements = functions.elements (); while (elements.hasMoreElements ()) { BrowserFunction function = ((BrowserFunction)elements.nextElement ()); AllFunctions.remove (new Integer (function.index)); function.dispose (false); } functions = null; delegate.onDispose (embedHandle); delegate = null; embedHandle = 0; BrowserCount--; } void Activate () { isActive = true; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]); rc = webBrowserFocus.Activate (); if (rc != XPCOM.NS_OK) error (rc); webBrowserFocus.Release (); } void Deactivate () { isActive = false; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebBrowserFocus.NS_IWEBBROWSERFOCUS_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebBrowserFocus webBrowserFocus = new nsIWebBrowserFocus (result[0]); rc = webBrowserFocus.Deactivate (); if (rc != XPCOM.NS_OK) error (rc); webBrowserFocus.Release (); } void navigate (long /*int*/ requestHandle) { nsIRequest request = new nsIRequest (requestHandle); /* get the request post data, if any */ long /*int*/[] result = new long /*int*/[1]; byte[] postData = null; final Vector headers = new Vector (); int rc = request.QueryInterface (nsIUploadChannel.NS_IUPLOADCHANNEL_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIUploadChannel uploadChannel = new nsIUploadChannel (result[0]); result[0] = 0; rc = uploadChannel.GetUploadStream (result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIInputStream inputStream = new nsIInputStream (result[0]); result[0] = 0; rc = inputStream.QueryInterface (nsISeekableStream.NS_ISEEKABLESTREAM_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsISeekableStream seekableStream = new nsISeekableStream (result[0]); result[0] = 0; long[] initialOffset = new long[1]; rc = seekableStream.Tell (initialOffset); if (rc == XPCOM.NS_OK) { rc = seekableStream.Seek (nsISeekableStream.NS_SEEK_SET, 0); if (rc == XPCOM.NS_OK) { long available; if (IsPre_17) { int[] _retval = new int[1]; rc = inputStream.Available (_retval); available = _retval[0]; } else { long[] _retval = new long[1]; rc = inputStream.Available (_retval); available = _retval[0]; } if (rc == XPCOM.NS_OK) { int length = (int)available; byte[] bytes = new byte[length]; int[] retVal = new int[1]; rc = inputStream.Read (bytes, length, retVal); if (rc == XPCOM.NS_OK) { int start = 0; for (int i = 0; i < length; i++) { if (bytes[i] == 13) { byte[] current = new byte[i - start]; System.arraycopy (bytes, start, current, 0, i - start); String string = new String (current).trim (); if (string.length () != 0) { headers.add (string); } else { start = i + 2; /* skip \r\n */ postData = new byte[length - start]; System.arraycopy (bytes, start, postData, 0, length - start); break; } start = i; } } } } } seekableStream.Seek (nsISeekableStream.NS_SEEK_SET, initialOffset[0]); } seekableStream.Release (); } inputStream.Release (); } uploadChannel.Release (); } /* get the request headers */ XPCOMObject visitor = new XPCOMObject (new int[] {2, 0, 0, 2}) { int refCount = 0; public long /*int*/ method0 (long /*int*/[] args) { /* QueryInterface */ long /*int*/ riid = args[0]; long /*int*/ ppvObject = args[1]; if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE; nsID guid = new nsID (); XPCOM.memmove (guid, riid, nsID.sizeof); if (guid.Equals (nsISupports.NS_ISUPPORTS_IID) || guid.Equals (XPCOM.NS_IHTTPHEADERVISITOR_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {getAddress ()}, C.PTR_SIZEOF); refCount++; return XPCOM.NS_OK; } XPCOM.memmove (ppvObject, new long /*int*/[] {0}, C.PTR_SIZEOF); return XPCOM.NS_ERROR_NO_INTERFACE; } public long /*int*/ method1 (long /*int*/[] args) { /* AddRef */ return ++refCount; } public long /*int*/ method2 (long /*int*/[] args) { /* Release */ if (--refCount == 0) dispose (); return refCount; } public long /*int*/ method3 (long /*int*/[] args) { /* VisitHeader */ long /*int*/ aHeader = args[0]; long /*int*/ aValue = args[1]; int length = XPCOM.nsEmbedCString_Length (aHeader); long /*int*/ buffer = XPCOM.nsEmbedCString_get (aHeader); byte[] dest = new byte[length]; XPCOM.memmove (dest, buffer, length); String header = new String (dest); length = XPCOM.nsEmbedCString_Length (aValue); buffer = XPCOM.nsEmbedCString_get (aValue); dest = new byte[length]; XPCOM.memmove (dest, buffer, length); String value = new String (dest); headers.add(header + ':' + value); return XPCOM.NS_OK; } }; new nsISupports (visitor.getAddress ()).AddRef (); rc = request.QueryInterface (nsIHttpChannel.NS_IHTTPCHANNEL_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { nsIHttpChannel httpChannel = new nsIHttpChannel (result[0]); result[0] = 0; httpChannel.VisitRequestHeaders (visitor.getAddress ()); httpChannel.Release (); } new nsISupports (visitor.getAddress ()).Release (); String[] headersArray = null; int size = headers.size (); if (size > 0) { headersArray = new String[size]; headers.copyInto (headersArray); } /* a request's name often (but not always) is its url */ String url = lastNavigateURL; long /*int*/ name = XPCOM.nsEmbedCString_new (); rc = request.GetName (name); if (rc == XPCOM.NS_OK) { int length = XPCOM.nsEmbedCString_Length (name); long /*int*/ buffer = XPCOM.nsEmbedCString_get (name); byte[] bytes = new byte[length]; XPCOM.memmove (bytes, buffer, length); String value = new String (bytes); if (value.indexOf (":/") != -1) url = value; //$NON-NLS-1$ } XPCOM.nsEmbedCString_delete (name); setUrl (url, postData, headersArray); } void onResize () { Rectangle rect = browser.getClientArea (); int width = Math.max (1, rect.width); int height = Math.max (1, rect.height); long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_10_IID, result); if (rc != XPCOM.NS_OK) { rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); if (rc != XPCOM.NS_OK) error (rc); } if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); delegate.setSize (embedHandle, width, height); nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); rc = baseWindow.SetPositionAndSize (0, 0, width, height, 1); if (rc != XPCOM.NS_OK) error (rc); baseWindow.Release (); } public void refresh () { htmlBytes = null; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error(rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); rc = webNavigation.Reload (nsIWebNavigation.LOAD_FLAGS_NONE); webNavigation.Release (); /* * The following error conditions do not indicate unrecoverable problems: * * - NS_ERROR_INVALID_POINTER: happens when Reload is called immediately * after calling LoadURI. * - NS_ERROR_FILE_NOT_FOUND: happens when attempting to reload a file that * no longer exists. * - NS_BINDING_ABORTED: happens when the user aborts the load (eg.- chooses * to not resubmit a page with form data). */ switch (rc) { case XPCOM.NS_OK: case XPCOM.NS_ERROR_INVALID_POINTER: case XPCOM.NS_ERROR_FILE_NOT_FOUND: case XPCOM.NS_BINDING_ABORTED: { return; } } error (rc); } void registerFunction (BrowserFunction function) { super.registerFunction (function); AllFunctions.put (new Integer (function.index), function); } boolean sendChangingEvent (String url) { isViewingErrorPage = url.indexOf ("netError.xhtml") != -1; //$NON-NLS-1$ boolean doit = true; if (request == 0) { /* * listeners should not be notified of internal transitions like "javascript:..." * because this is an implementation side-effect, not a true navigate */ if (!url.startsWith (PREFIX_JAVASCRIPT)) { if (locationListeners.length > 0) { LocationEvent event = new LocationEvent (browser); event.display = browser.getDisplay(); event.widget = browser; event.location = url; /* * If the URI indicates that the page is being rendered from memory * (via setText()) then set it to about:blank to be consistent with IE. */ if (event.location.equals (URI_FILEROOT)) { event.location = ABOUT_BLANK; } else { int length = URI_FILEROOT.length (); if (event.location.startsWith (URI_FILEROOT) && event.location.charAt (length) == '#') { event.location = ABOUT_BLANK + event.location.substring (length); } } event.doit = doit; for (int i = 0; i < locationListeners.length; i++) { locationListeners[i].changing (event); } doit = event.doit && !browser.isDisposed(); } if (doit) { if (jsEnabled != jsEnabledOnNextPage) { jsEnabled = jsEnabledOnNextPage; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebBrowserSetup.NS_IWEBBROWSERSETUP_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIWebBrowserSetup setup = new nsIWebBrowserSetup (result[0]); result[0] = 0; rc = setup.SetProperty (nsIWebBrowserSetup.SETUP_ALLOW_JAVASCRIPT, jsEnabled ? 1 : 0); if (rc != XPCOM.NS_OK) error (rc); setup.Release (); } if (!isViewingErrorPage) lastNavigateURL = url; } } } return doit; } public boolean setText (String html, boolean trusted) { /* * Feature in Mozilla. The focus memory of Mozilla must be * properly managed through the nsIWebBrowserFocus interface. * In particular, nsIWebBrowserFocus.deactivate must be called * when the focus moves from the browser (or one of its children * managed by Mozilla to another widget. We currently do not * get notified when a widget takes focus away from the Browser. * As a result, deactivate is not properly called. This causes * Mozilla to retake focus the next time a document is loaded. * This breaks the case where the HTML loaded in the Browser * varies while the user enters characters in a text widget. The text * widget loses focus every time new content is loaded. * The current workaround is to call deactivate everytime if * the browser currently does not have focus. A better workaround * would be to have a way to call deactivate when the Browser * or one of its children loses focus. */ if (browser != browser.getDisplay ().getFocusControl ()) Deactivate (); /* convert the String containing HTML to an array of bytes with UTF-8 data */ byte[] data = null; try { data = html.getBytes ("UTF-8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException e) { return false; } /* * This could be the first content that is set into the browser, so * ensure that the custom subclass that works around Mozilla bug * https://bugzilla.mozilla.org/show_bug.cgi?id=453523 is removed. */ delegate.removeWindowSubclass (); long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result); if (rc == XPCOM.NS_OK && result[0] != 0) { /* * Setting mozilla's content through nsIWebBrowserStream does not cause a page * load to occur, so the events that usually accompany a page change are not * fired. To make this behave as expected, navigate to about:blank first and * then set the html content once the page has loaded. */ new nsISupports (result[0]).Release (); result[0] = 0; /* * If htmlBytes is not null then the about:blank page is already being loaded, * so no Navigate is required. Just set the html that is to be shown. */ boolean blankLoading = htmlBytes != null; htmlBytes = data; untrustedText = !trusted; if (blankLoading) return true; /* navigate to about:blank */ rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); result[0] = 0; char[] uri = new char[ABOUT_BLANK.length () + 1]; ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uri, 0); rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0); if (rc != XPCOM.NS_OK) error (rc); webNavigation.Release (); } else { byte[] contentCharsetBuffer = MozillaDelegate.wcsToMbcs (null, "UTF-8", false); //$NON-NLS-1$ long /*int*/ aContentCharset = XPCOM.nsEmbedCString_new (contentCharsetBuffer, contentCharsetBuffer.length); byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", false); // $NON-NLS-1$ long /*int*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length); rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIIOService ioService = new nsIIOService (result[0]); result[0] = 0; byte[] aString; if (trusted) { aString = MozillaDelegate.wcsToMbcs (null, URI_FILEROOT, false); } else { aString = MozillaDelegate.wcsToMbcs (null, ABOUT_BLANK, false); } long /*int*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length); rc = ioService.NewURI (aSpec, null, 0, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); XPCOM.nsEmbedCString_delete (aSpec); ioService.Release (); nsIURI uri = new nsIURI (result[0]); result[0] = 0; rc = webBrowser.QueryInterface (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIInterfaceRequestor interfaceRequestor = new nsIInterfaceRequestor (result[0]); result[0] = 0; /* * Feature in Mozilla. LoadStream invokes the nsIInputStream argument * through a different thread. The callback mechanism must attach * a non java thread to the JVM otherwise the nsIInputStream Read and * Close methods never get called. */ InputStream inputStream = new InputStream (data); inputStream.AddRef (); rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDocShell docShell = new nsIDocShell (result[0]); result[0] = 0; rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0); docShell.Release (); inputStream.Release (); interfaceRequestor.Release (); uri.Release (); XPCOM.nsEmbedCString_delete (aContentType); XPCOM.nsEmbedCString_delete (aContentCharset); } return true; } public boolean setUrl (String url, String postData, String[] headers) { byte[] postDataBytes = null; if (postData != null) { postDataBytes = MozillaDelegate.wcsToMbcs (null, postData, false); } return setUrl (url, postDataBytes, headers); } boolean setUrl (String url, byte[] postData, String[] headers) { htmlBytes = null; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); /* * This could be the first content that is set into the browser, so * ensure that the custom subclass that works around Mozilla bug * https://bugzilla.mozilla.org/show_bug.cgi?id=453523 is removed. */ delegate.removeWindowSubclass (); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); result[0] = 0; char[] uri = new char[url.length () + 1]; url.getChars (0, url.length (), uri, 0); nsIMIMEInputStream postDataStream = null; InputStream dataStream = null; if (postData != null) { rc = XPCOM.NS_GetComponentManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIComponentManager componentManager = new nsIComponentManager (result[0]); result[0] = 0; byte[] contractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_MIMEINPUTSTREAM_CONTRACTID, true); rc = componentManager.CreateInstanceByContractID (contractID, 0, nsIMIMEInputStream.NS_IMIMEINPUTSTREAM_IID, result); componentManager.Release(); if (rc == XPCOM.NS_OK && result[0] != 0) { /* nsIMIMEInputStream is not in mozilla 1.4 */ dataStream = new InputStream (postData); dataStream.AddRef (); postDataStream = new nsIMIMEInputStream (result[0]); rc = postDataStream.SetData (dataStream.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); boolean foundLength = false; boolean foundType = false; if (headers != null) { for (int i = 0; i < headers.length; i++) { int index = headers[i].indexOf (':'); if (index != -1) { String name = headers[i].substring (0, index).trim ().toLowerCase (); if (name.equals (HEADER_CONTENTLENGTH)) { foundLength = true; } else if (name.equals (HEADER_CONTENTTYPE)) { foundType = true; } } } } rc = postDataStream.SetAddContentLength (foundLength ? 0 : 1); if (rc != XPCOM.NS_OK) error (rc); if (!foundType) { byte[] name = MozillaDelegate.wcsToMbcs (null, HEADER_CONTENTTYPE, true); byte[] value = MozillaDelegate.wcsToMbcs (null, MIMETYPE_FORMURLENCODED, true); rc = postDataStream.AddHeader (name, value); if (rc != XPCOM.NS_OK) error (rc); } } result[0] = 0; } InputStream headersStream = null; if (headers != null) { StringBuffer buffer = new StringBuffer (); for (int i = 0; i < headers.length; i++) { String current = headers[i]; if (current != null) { int sep = current.indexOf (':'); if (sep != -1) { String key = current.substring (0, sep).trim (); String value = current.substring (sep + 1).trim (); if (key.length () > 0 && value.length () > 0) { buffer.append (key); buffer.append (':'); buffer.append (value); buffer.append ("\r\n"); } } } } byte[] bytes = MozillaDelegate.wcsToMbcs (null, buffer.toString (), true); headersStream = new InputStream (bytes); headersStream.AddRef (); } rc = webNavigation.LoadURI ( uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, postDataStream == null ? 0 : postDataStream.getAddress (), headersStream == null ? 0 : headersStream.getAddress ()); if (dataStream != null) dataStream.Release (); if (headersStream != null) headersStream.Release (); webNavigation.Release (); return rc == XPCOM.NS_OK; } public void stop () { htmlBytes = null; long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]); rc = webNavigation.Stop (nsIWebNavigation.STOP_ALL); if (rc != XPCOM.NS_OK) error (rc); webNavigation.Release (); } void hookDOMListeners (nsIDOMEventTarget target, boolean isTop) { nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); /* * Only hook mouseover and mouseout if the target is a top-level frame, so that mouse moves * between frames will not generate events. */ if (isTop && delegate.hookEnterExit ()) { string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); } string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP); target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0, 1, 0); string.dispose (); } void unhookDOMListeners () { long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.GetContentDOMWindow (result); if (rc != XPCOM.NS_OK || result[0] == 0) return; nsIDOMWindow window = new nsIDOMWindow (result[0]); result[0] = 0; rc = window.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID : nsIDOMEventTarget.NS_IDOMEVENTTARGET_10_IID) : nsIDOMEventTarget.NS_IDOMEVENTTARGET_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); result[0] = 0; unhookDOMListeners (target); target.Release (); /* Listeners must be unhooked in pages contained in frames */ rc = window.GetFrames (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMWindowCollection frames = new nsIDOMWindowCollection (result[0]); result[0] = 0; int[] frameCount = new int[1]; rc = frames.GetLength (frameCount); /* PRUint32 */ if (rc != XPCOM.NS_OK) error (rc); int count = frameCount[0]; if (count > 0) { for (int i = 0; i < count; i++) { rc = frames.Item (i, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMWindow frame = new nsIDOMWindow (result[0]); result[0] = 0; rc = frame.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID : nsIDOMEventTarget.NS_IDOMEVENTTARGET_10_IID) : nsIDOMEventTarget.NS_IDOMEVENTTARGET_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); target = new nsIDOMEventTarget (result[0]); result[0] = 0; unhookDOMListeners (target); target.Release (); frame.Release (); } } frames.Release (); window.Release (); } void unhookDOMListeners (nsIDOMEventTarget target) { nsEmbedString string = new nsEmbedString (XPCOM.DOMEVENT_FOCUS); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOVER); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP); target.RemoveEventListener (string.getAddress (), domEventListener.getAddress (), 0); string.dispose (); } /* nsISupports */ int QueryInterface (long /*int*/ riid, long /*int*/ ppvObject) { if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE; nsID guid = new nsID (); XPCOM.memmove (guid, riid, nsID.sizeof); if (guid.Equals (nsISupports.NS_ISUPPORTS_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {supports.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_IWEAKREFERENCE_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {webProgressListener.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_17_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {webProgressListener_17.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (nsIWebBrowserChrome.NS_IWEBBROWSERCHROME_IID) || guid.Equals (nsIWebBrowserChrome.NS_IWEBBROWSERCHROME_17_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {webBrowserChrome.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_IWEBBROWSERCHROMEFOCUS_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {webBrowserChromeFocus.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {embeddingSiteWindow.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_17_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {embeddingSiteWindow_17.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {interfaceRequestor.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_ISUPPORTSWEAKREFERENCE_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {supportsWeakReference.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_ICONTEXTMENULISTENER_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {contextMenuListener.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_IURICONTENTLISTENER_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {uriContentListener.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_ITOOLTIPLISTENER_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {tooltipListener.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } if (guid.Equals (XPCOM.NS_IBADCERTLISTENER2_IID)) { XPCOM.memmove (ppvObject, new long /*int*/[] {badCertListener.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } XPCOM.memmove (ppvObject, new long /*int*/[] {0}, C.PTR_SIZEOF); return XPCOM.NS_ERROR_NO_INTERFACE; } int AddRef () { refCount++; return refCount; } int Release () { refCount--; if (refCount == 0) disposeCOMInterfaces (); return refCount; } /* nsIWeakReference */ int QueryReferent (long /*int*/ riid, long /*int*/ ppvObject) { return QueryInterface (riid, ppvObject); } /* nsIInterfaceRequestor */ int GetInterface (long /*int*/ riid, long /*int*/ ppvObject) { if (riid == 0 || ppvObject == 0) return XPCOM.NS_ERROR_NO_INTERFACE; nsID guid = new nsID (); XPCOM.memmove (guid, riid, nsID.sizeof); if (guid.Equals (nsIDOMWindow.NS_IDOMWINDOW_17_IID) || guid.Equals (nsIDOMWindow.NS_IDOMWINDOW_10_IID) || guid.Equals (nsIDOMWindow.NS_IDOMWINDOW_IID)) { long /*int*/[] aContentDOMWindow = new long /*int*/[1]; int rc = webBrowser.GetContentDOMWindow (aContentDOMWindow); if (rc != XPCOM.NS_OK) error (rc); if (aContentDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); XPCOM.memmove (ppvObject, aContentDOMWindow, C.PTR_SIZEOF); return rc; } return QueryInterface (riid, ppvObject); } int GetWeakReference (long /*int*/ ppvObject) { XPCOM.memmove (ppvObject, new long /*int*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF); AddRef (); return XPCOM.NS_OK; } /* nsIWebProgressListener */ int OnStateChange (long /*int*/ aWebProgress, long /*int*/ aRequest, int aStateFlags, int aStatus) { if (registerFunctionsOnState != 0 && ((aStateFlags & registerFunctionsOnState) == registerFunctionsOnState)) { registerFunctionsOnState = 0; Enumeration elements = functions.elements (); while (elements.hasMoreElements ()) { BrowserFunction function = (BrowserFunction)elements.nextElement (); if (!function.isEvaluate) { execute (function.functionString); } } } /* * Feature of Mozilla. When a redirect occurs, no STATE_IS_DOCUMENT state * transitions or OnStartURIOpen() callbacks are received for the new * location. As a result, lastNavigateURL is left with the value of the old * url (that was redirected from), and the client does not get an opportunity * to veto the redirect. The only opportunity to work around these omissions * is in the subsequent STATE_START | STATE_IS_REQUEST state transition. * When this comes, if the request's name appears to be a url then take it to * be the new site (update lastNavigateURL), and send a "changing" LocationEvent * to allow the redirect to be vetoed. * * Note that updateLastNavigateUrl is not reset to false here so that in * typical contexts where a redirect occurs without an accompanying invalid * certificate, the updated site will be retrieved from the channel (this * is more proper) on the next STATE_TRANSFERRING | STATE_IS_DOCUMENT transition. */ if (updateLastNavigateUrl && aStateFlags == (nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_START)) { nsIRequest request = new nsIRequest (aRequest); long /*int*/ name = XPCOM.nsEmbedCString_new (); int rc = request.GetName (name); if (rc == XPCOM.NS_OK) { int length = XPCOM.nsEmbedCString_Length (name); long /*int*/ buffer = XPCOM.nsEmbedCString_get (name); byte[] bytes = new byte[length]; XPCOM.memmove (bytes, buffer, length); String value = new String (bytes); if (value.indexOf (":/") != -1) { //$NON-NLS-1$ boolean doit = sendChangingEvent (value); if (doit) { lastNavigateURL = value; } else { stop (); } } } XPCOM.nsEmbedCString_delete (name); } if ((aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) == 0) return XPCOM.NS_OK; if ((aStateFlags & nsIWebProgressListener.STATE_START) != 0) { long /*int*/[] result = new long /*int*/[1]; /* * When navigating to a site that is known to have a bad certificate, request notification * callbacks on the channel so that our nsIBadCertListener2 will be invoked. */ if (isRetrievingBadCert) { nsIRequest request = new nsIRequest (aRequest); int rc = request.QueryInterface (nsIChannel.NS_ICHANNEL_10_IID, result); if (rc != XPCOM.NS_OK) { rc = request.QueryInterface (nsIChannel.NS_ICHANNEL_IID, result); if (rc != XPCOM.NS_OK) error (rc); } if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIChannel channel = new nsIChannel (result[0]); result[0] = 0; rc = channel.SetNotificationCallbacks (interfaceRequestor.getAddress ()); if (rc != XPCOM.NS_OK) error (rc); channel.Release (); return XPCOM.NS_OK; } if (request == 0) request = aRequest; registerFunctionsOnState = nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_START; /* * Add the page's nsIDOMWindow to the collection of windows that will * have DOM listeners added to them later on in the page loading * process. These listeners cannot be added yet because the * nsIDOMWindow is not ready to take them at this stage. */ nsIWebProgress progress = new nsIWebProgress (aWebProgress); int rc = progress.GetDOMWindow (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); unhookedDOMWindows.addElement (new LONG (result[0])); } else if ((aStateFlags & nsIWebProgressListener.STATE_REDIRECTING) != 0) { if (request == aRequest) request = 0; registerFunctionsOnState = nsIWebProgressListener.STATE_TRANSFERRING; updateLastNavigateUrl = true; } else if ((aStateFlags & nsIWebProgressListener.STATE_STOP) != 0) { if (isRetrievingBadCert) { isRetrievingBadCert = false; return XPCOM.NS_OK; } /* * If a site with a bad certificate is being encountered for the first time * then store the request for future reference, set the isRetrievingBadCert * flag and re-navigate to the site so that notification callbacks can be * hooked on it to get its certificate info. */ switch (aStatus) { case XPCOM.SSL_ERROR_BAD_CERT_DOMAIN: case XPCOM.SEC_ERROR_CA_CERT_INVALID: case XPCOM.SEC_ERROR_EXPIRED_CERTIFICATE: case XPCOM.SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: case XPCOM.SEC_ERROR_INADEQUATE_KEY_USAGE: case XPCOM.SEC_ERROR_UNKNOWN_ISSUER: case XPCOM.SEC_ERROR_UNTRUSTED_CERT: case XPCOM.SEC_ERROR_UNTRUSTED_ISSUER: { new nsISupports (aRequest).AddRef (); if (badCertRequest != 0) { new nsISupports (badCertRequest).Release (); } badCertRequest = aRequest; isRetrievingBadCert = true; navigate (aRequest); return XPCOM.NS_OK; } } /* * If this page's nsIDOMWindow handle is still in unhookedDOMWindows then * add its DOM listeners now. It's possible for this to happen since * there is no guarantee that a STATE_TRANSFERRING state change will be * received for every window in a page, which is when these listeners * are typically added. */ long /*int*/[] result = new long /*int*/[1]; int rc; LONG ptrObject = new LONG (result[0]); result[0] = 0; int index = unhookedDOMWindows.indexOf (ptrObject); if (index != -1) { long /*int*/[] window = new long /*int*/[1]; nsIWebProgress progress = new nsIWebProgress (aWebProgress); rc = progress.GetDOMWindow (window); if (rc != XPCOM.NS_OK) error (rc); if (window[0] == 0) error (XPCOM.NS_NOINTERFACE); rc = webBrowser.GetContentDOMWindow (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); boolean isTop = result[0] == window[0]; new nsISupports (result[0]).Release (); result[0] = 0; nsIDOMWindow domWindow = new nsIDOMWindow (window[0]); rc = domWindow.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID : nsIDOMEventTarget.NS_IDOMEVENTTARGET_10_IID) : nsIDOMEventTarget.NS_IDOMEVENTTARGET_17_IID, result); domWindow.Release(); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); hookDOMListeners (target, isTop); target.Release (); result[0] = 0; /* * Remove and unreference the nsIDOMWindow from the collection of windows * that are waiting to have DOM listeners hooked on them. */ unhookedDOMWindows.remove (ptrObject); new nsISupports (ptrObject.value).Release (); } boolean deferCompleted = false; /* * If htmlBytes is not null then there is html from a previous setText() call * waiting to be set into the about:blank page once it has completed loading. */ if (htmlBytes != null) { nsIRequest req = new nsIRequest (aRequest); long /*int*/ name = XPCOM.nsEmbedCString_new (); rc = req.GetName (name); if (rc != XPCOM.NS_OK) error (rc); int length = XPCOM.nsEmbedCString_Length (name); long /*int*/ buffer = XPCOM.nsEmbedCString_get (name); byte[] dest = new byte[length]; XPCOM.memmove (dest, buffer, length); String url = new String (dest); XPCOM.nsEmbedCString_delete (name); if (url.startsWith (ABOUT_BLANK)) { /* * Setting mozilla's content with nsIWebBrowserStream invalidates the * DOM listeners that were hooked on it (about:blank), so remove them and * add new ones after the content has been set. */ unhookDOMListeners (); rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); serviceManager.Release (); nsIIOService ioService = new nsIIOService (result[0]); result[0] = 0; byte[] aString; if (untrustedText) { aString = MozillaDelegate.wcsToMbcs (null, ABOUT_BLANK, false); } else { aString = MozillaDelegate.wcsToMbcs (null, URI_FILEROOT, false); } long /*int*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length); rc = ioService.NewURI (aSpec, null, 0, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); XPCOM.nsEmbedCString_delete (aSpec); ioService.Release (); nsIURI uri = new nsIURI (result[0]); result[0] = 0; rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIWebBrowserStream stream = new nsIWebBrowserStream (result[0]); result[0] = 0; byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", false); // $NON-NLS-1$ long /*int*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length); rc = stream.OpenStream (uri.getAddress (), aContentType); if (rc != XPCOM.NS_OK) error (rc); /* * For Mozilla < 1.9.2, when content is being set via nsIWebBrowserStream, this * is the only place where registered functions can be re-installed such that * they will be invokable at load time by JS contained in the text. */ Enumeration elements = functions.elements (); while (elements.hasMoreElements ()) { BrowserFunction function = (BrowserFunction)elements.nextElement (); if (!function.isEvaluate) { execute (function.functionString); } } /* * For Mozilla >= 1.9.2, when content is being set via nsIWebBrowserStream, * registered functions must be re-installed in the subsequent Start Request * in order to be invokable at load time by JS contained in the text. */ registerFunctionsOnState = nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_START; long /*int*/ ptr = C.malloc (htmlBytes.length); XPCOM.memmove (ptr, htmlBytes, htmlBytes.length); int pageSize = 8192; int pageCount = htmlBytes.length / pageSize + 1; long /*int*/ current = ptr; for (int i = 0; i < pageCount; i++) { length = i == pageCount - 1 ? htmlBytes.length % pageSize : pageSize; if (length > 0) { rc = stream.AppendToStream (current, length); if (rc != XPCOM.NS_OK) error (rc); } current += pageSize; } rc = stream.CloseStream (); if (rc != XPCOM.NS_OK) error (rc); C.free (ptr); XPCOM.nsEmbedCString_delete (aContentType); stream.Release (); uri.Release (); htmlBytes = null; /* * Browser content that is set via nsIWebBrowserStream is not parsed immediately. * Since clients depend on the Completed event to know when the browser's content * is available, delay the sending of this event so that the stream content will * be parsed first. */ deferCompleted = true; long /*int*/[] window = new long /*int*/[1]; nsIWebProgress progress = new nsIWebProgress (aWebProgress); rc = progress.GetDOMWindow (window); if (rc != XPCOM.NS_OK) error (rc); if (window[0] == 0) error (XPCOM.NS_NOINTERFACE); rc = webBrowser.GetContentDOMWindow (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); boolean isTop = result[0] == window[0]; new nsISupports (result[0]).Release (); result[0] = 0; nsIDOMWindow domWindow = new nsIDOMWindow (window[0]); rc = domWindow.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID : nsIDOMEventTarget.NS_IDOMEVENTTARGET_10_IID) : nsIDOMEventTarget.NS_IDOMEVENTTARGET_17_IID, result); domWindow.Release(); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); hookDOMListeners (target, isTop); target.Release (); result[0] = 0; } else { registerFunctionsOnState = 0; } } /* * Feature in Mozilla. When a request is redirected (STATE_REDIRECTING), * it never reaches the state STATE_STOP and it is replaced with a new request. * The new request is received when it is in the state STATE_STOP. * To handle this case, the variable request is set to 0 when the corresponding * request is redirected. The following request received with the state STATE_STOP * - the new request resulting from the redirection - is used to send * the ProgressListener.completed event. */ if (request == aRequest || request == 0) { request = 0; StatusTextEvent event = new StatusTextEvent (browser); event.display = browser.getDisplay (); event.widget = browser; event.text = ""; //$NON-NLS-1$ for (int i = 0; i < statusTextListeners.length; i++) { statusTextListeners[i].changed (event); } final Display display = browser.getDisplay (); final ProgressEvent event2 = new ProgressEvent (browser); event2.display = display; event2.widget = browser; Runnable runnable = new Runnable () { public void run () { if (browser.isDisposed ()) return; for (int i = 0; i < progressListeners.length; i++) { progressListeners[i].completed (event2); } } }; if (deferCompleted) { display.asyncExec (runnable); } else { display.syncExec (runnable); } } } else if ((aStateFlags & nsIWebProgressListener.STATE_TRANSFERRING) != 0) { if (!IsPre_4) { registerFunctionsOnState = nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_STOP; } if (updateLastNavigateUrl) { updateLastNavigateUrl = false; nsIRequest request = new nsIRequest (aRequest); long /*int*/[] result = new long /*int*/[1]; int rc = request.QueryInterface (nsIChannel.NS_ICHANNEL_10_IID, result); if (rc != XPCOM.NS_OK) { rc = request.QueryInterface (nsIChannel.NS_ICHANNEL_IID, result); } if (rc == XPCOM.NS_OK && result[0] != 0) { nsIChannel channel = new nsIChannel (result[0]); result[0] = 0; rc = channel.GetURI (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); channel.Release (); nsIURI uri = new nsIURI (result[0]); result[0] = 0; long /*int*/ aSpec = XPCOM.nsEmbedCString_new (); rc = uri.GetSpec (aSpec); if (rc != XPCOM.NS_OK) error (rc); int length = XPCOM.nsEmbedCString_Length (aSpec); long /*int*/ buffer = XPCOM.nsEmbedCString_get (aSpec); byte[] bytes = new byte[length]; XPCOM.memmove (bytes, buffer, length); lastNavigateURL = new String (bytes); XPCOM.nsEmbedCString_delete (aSpec); uri.Release (); } } /* * Hook DOM listeners to the page's nsIDOMWindow here because this is * the earliest opportunity to do so. */ long /*int*/[] result = new long /*int*/[1]; nsIWebProgress progress = new nsIWebProgress (aWebProgress); int rc = progress.GetDOMWindow (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMWindow domWindow = new nsIDOMWindow (result[0]); LONG ptrObject = new LONG (result[0]); result[0] = 0; int index = unhookedDOMWindows.indexOf (ptrObject); if (index != -1) { rc = webBrowser.GetContentDOMWindow (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); boolean isTop = result[0] == domWindow.getAddress (); new nsISupports (result[0]).Release (); result[0] = 0; rc = domWindow.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID : nsIDOMEventTarget.NS_IDOMEVENTTARGET_10_IID) : nsIDOMEventTarget.NS_IDOMEVENTTARGET_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); hookDOMListeners (target, isTop); target.Release (); result[0] = 0; /* * Remove and unreference the nsIDOMWindow from the collection of windows * that are waiting to have DOM listeners hooked on them. */ unhookedDOMWindows.remove (ptrObject); new nsISupports (ptrObject.value).Release (); } domWindow.Release (); } return XPCOM.NS_OK; } int OnProgressChange (long /*int*/ aWebProgress, long /*int*/ aRequest, int aCurSelfProgress, int aMaxSelfProgress, int aCurTotalProgress, int aMaxTotalProgress) { if (progressListeners.length == 0) return XPCOM.NS_OK; ProgressEvent event = new ProgressEvent (browser); event.display = browser.getDisplay (); event.widget = browser; event.current = aCurTotalProgress; event.total = aMaxTotalProgress; for (int i = 0; i < progressListeners.length; i++) { progressListeners[i].changed (event); } return XPCOM.NS_OK; } int OnLocationChange (long /*int*/ aWebProgress, long /*int*/ aRequest, long /*int*/ aLocation) { return OnLocationChange(aWebProgress, aRequest, aLocation, 0); } int OnLocationChange (long /*int*/ aWebProgress, long /*int*/ aRequest, long /*int*/ aLocation, int aFlags) { /* * Feature in Mozilla. When a page is loaded via setText before a previous * setText page load has completed, the expected OnStateChange STATE_STOP for the * original setText never arrives because it gets replaced by the OnStateChange * STATE_STOP for the new request. This results in the request field never being * cleared because the original request's OnStateChange STATE_STOP is still expected * (but never arrives). To handle this case, the request field is updated to the new * overriding request since its OnStateChange STATE_STOP will be received next. */ if (request != 0 && request != aRequest) request = aRequest; if (locationListeners.length == 0) return XPCOM.NS_OK; nsIWebProgress webProgress = new nsIWebProgress (aWebProgress); long /*int*/[] aDOMWindow = new long /*int*/[1]; int rc = webProgress.GetDOMWindow (aDOMWindow); if (rc != XPCOM.NS_OK) error (rc); if (aDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); long /*int*/[] aTop = new long /*int*/[1]; nsIDOMWindow domWindow = new nsIDOMWindow (aDOMWindow[0]); rc = domWindow.GetTop (aTop); domWindow.Release (); if (rc != XPCOM.NS_OK) error (rc); if (aTop[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIDOMWindow topWindow = new nsIDOMWindow (aTop[0]); topWindow.Release (); nsIURI location = new nsIURI (aLocation); long /*int*/ aSpec = XPCOM.nsEmbedCString_new (); location.GetSpec (aSpec); int length = XPCOM.nsEmbedCString_Length (aSpec); long /*int*/ buffer = XPCOM.nsEmbedCString_get (aSpec); byte[] dest = new byte[length]; XPCOM.memmove (dest, buffer, length); XPCOM.nsEmbedCString_delete (aSpec); String url = new String (dest); /* * As of Mozilla 1.8, the first time that a page is displayed, regardless of * whether it's via Browser.setURL() or Browser.setText(), the GRE navigates * to about:blank and fires the corresponding navigation events. Do not send * this event on to the user since it is not expected. */ if (!IsPre_1_8 && aRequest == 0 && url.startsWith (ABOUT_BLANK)) return XPCOM.NS_OK; LocationEvent event = new LocationEvent (browser); event.display = browser.getDisplay (); event.widget = browser; event.location = url; /* * If the URI indicates that the page is being rendered from memory * (via setText()) then set it to about:blank to be consistent with IE. */ if (event.location.equals (URI_FILEROOT)) { event.location = ABOUT_BLANK; } else { length = URI_FILEROOT.length (); if (event.location.startsWith (URI_FILEROOT) && event.location.charAt (length) == '#') { event.location = ABOUT_BLANK + event.location.substring (length); } } event.top = aTop[0] == aDOMWindow[0]; for (int i = 0; i < locationListeners.length; i++) { locationListeners[i].changed (event); } return XPCOM.NS_OK; } int OnStatusChange (long /*int*/ aWebProgress, long /*int*/ aRequest, int aStatus, long /*int*/ aMessage) { if (statusTextListeners.length == 0) return XPCOM.NS_OK; StatusTextEvent event = new StatusTextEvent (browser); event.display = browser.getDisplay (); event.widget = browser; int length = XPCOM.strlen_PRUnichar (aMessage); char[] dest = new char[length]; XPCOM.memmove (dest, aMessage, length * 2); event.text = new String (dest); for (int i = 0; i < statusTextListeners.length; i++) { statusTextListeners[i].changed (event); } return XPCOM.NS_OK; } int OnSecurityChange (long /*int*/ aWebProgress, long /*int*/ aRequest, int state) { return XPCOM.NS_OK; } /* nsIWebBrowserChrome */ int SetStatus (int statusType, long /*int*/ status) { if (statusTextListeners.length == 0) return XPCOM.NS_OK; StatusTextEvent event = new StatusTextEvent (browser); event.display = browser.getDisplay (); event.widget = browser; int length = XPCOM.strlen_PRUnichar (status); char[] dest = new char[length]; XPCOM.memmove (dest, status, length * 2); String string = new String (dest); event.text = string; for (int i = 0; i < statusTextListeners.length; i++) { statusTextListeners[i].changed (event); } return XPCOM.NS_OK; } int GetWebBrowser (long /*int*/ aWebBrowser) { long /*int*/[] ret = new long /*int*/[1]; if (webBrowser != null) { webBrowser.AddRef (); ret[0] = webBrowser.getAddress (); } XPCOM.memmove (aWebBrowser, ret, C.PTR_SIZEOF); return XPCOM.NS_OK; } int SetWebBrowser (long /*int*/ aWebBrowser) { if (webBrowser != null) webBrowser.Release (); webBrowser = aWebBrowser != 0 ? new nsIWebBrowser (aWebBrowser) : null; return XPCOM.NS_OK; } int GetChromeFlags (long /*int*/ aChromeFlags) { int[] ret = new int[1]; ret[0] = chromeFlags; XPCOM.memmove (aChromeFlags, ret, 4); /* PRUint32 */ return XPCOM.NS_OK; } int SetChromeFlags (int aChromeFlags) { chromeFlags = aChromeFlags; return XPCOM.NS_OK; } int DestroyBrowserWindow () { WindowEvent newEvent = new WindowEvent (browser); newEvent.display = browser.getDisplay (); newEvent.widget = browser; for (int i = 0; i < closeWindowListeners.length; i++) { closeWindowListeners[i].close (newEvent); } /* * Note on Mozilla. The DestroyBrowserWindow notification cannot be cancelled. * The browser widget cannot be used after this notification has been received. * The application is advised to close the window hosting the browser widget. * The browser widget must be disposed in all cases. */ browser.dispose (); return XPCOM.NS_OK; } int SizeBrowserTo (int aCX, int aCY) { size = new Point (aCX, aCY); boolean isChrome = (chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0; if (isChrome) { Shell shell = browser.getShell (); shell.setSize (shell.computeSize (size.x, size.y)); } return XPCOM.NS_OK; } int ShowAsModal () { long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_CONTEXTSTACK_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsIJSContextStack.NS_IJSCONTEXTSTACK_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); serviceManager.Release (); nsIJSContextStack stack = new nsIJSContextStack (result[0]); result[0] = 0; rc = stack.Push (0); if (rc != XPCOM.NS_OK) error (rc); Shell shell = browser.getShell (); Display display = browser.getDisplay (); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } rc = stack.Pop (result); if (rc != XPCOM.NS_OK) error (rc); stack.Release (); return XPCOM.NS_OK; } int IsWindowModal (long /*int*/ retval) { boolean result = (chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) != 0; XPCOM.memmove (retval, new boolean[] {result}); return XPCOM.NS_OK; } int ExitModalEventLoop (int aStatus) { return XPCOM.NS_OK; } /* nsIEmbeddingSiteWindow */ int SetDimensions (int flags, int x, int y, int cx, int cy) { boolean isChrome = (chromeFlags & nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0; if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) != 0) { location = new Point (x, y); if (isChrome) { browser.getShell ().setLocation (x, y); } } if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_INNER) != 0) { size = new Point (cx, cy); if (isChrome) { browser.setSize (cx, cy); } } if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_OUTER) != 0) { if (isChrome) { browser.getShell ().setSize (cx, cy); } } return XPCOM.NS_OK; } int GetDimensions (int flags, long /*int*/ x, long /*int*/ y, long /*int*/ cx, long /*int*/ cy) { if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_POSITION) != 0) { Point location = browser.getShell ().getLocation (); if (x != 0) C.memmove (x, new int[] {location.x}, 4); /* PRInt32 */ if (y != 0) C.memmove (y, new int[] {location.y}, 4); /* PRInt32 */ } if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_INNER) != 0) { Point size = browser.getSize (); if (cx != 0) C.memmove (cx, new int[] {size.x}, 4); /* PRInt32 */ if (cy != 0) C.memmove (cy, new int[] {size.y}, 4); /* PRInt32 */ } if ((flags & nsIEmbeddingSiteWindow.DIM_FLAGS_SIZE_OUTER) != 0) { Point size = browser.getShell().getSize (); if (cx != 0) C.memmove (cx, new int[] {size.x}, 4); /* PRInt32 */ if (cy != 0) C.memmove (cy, new int[] {size.y}, 4); /* PRInt32 */ } return XPCOM.NS_OK; } int SetFocus () { long /*int*/[] result = new long /*int*/[1]; int rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_10_IID, result); if (rc != XPCOM.NS_OK) { rc = webBrowser.QueryInterface (nsIBaseWindow.NS_IBASEWINDOW_IID, result); if (rc != XPCOM.NS_OK) error (rc); } if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); nsIBaseWindow baseWindow = new nsIBaseWindow (result[0]); rc = baseWindow.SetFocus (); if (rc != XPCOM.NS_OK) error (rc); baseWindow.Release (); /* * Note. Mozilla notifies here that one of the children took * focus. This could or should be used to fire an SWT.FOCUS_IN * event on Browser focus listeners. */ return XPCOM.NS_OK; } int GetVisibility (long /*int*/ aVisibility) { boolean visible = browser.isVisible () && !browser.getShell ().getMinimized (); XPCOM.memmove (aVisibility, new boolean[] {visible}); return XPCOM.NS_OK; } int SetVisibility (int aVisibility) { if (isChild) { WindowEvent event = new WindowEvent (browser); event.display = browser.getDisplay (); event.widget = browser; if (aVisibility != 0) { /* * Bug in Mozilla. When the JavaScript window.open is executed, Mozilla * fires multiple SetVisibility 1 notifications. The workaround is * to ignore subsequent notifications. */ if (!visible) { visible = true; event.location = location; event.size = size; event.addressBar = (chromeFlags & nsIWebBrowserChrome.CHROME_LOCATIONBAR) != 0; /* Feature of OSX. The menu bar is always displayed. */ boolean isOSX = Platform.PLATFORM.equals ("cocoa") || Platform.PLATFORM.equals ("carbon"); event.menuBar = isOSX || (chromeFlags & nsIWebBrowserChrome.CHROME_MENUBAR) != 0; event.statusBar = (chromeFlags & nsIWebBrowserChrome.CHROME_STATUSBAR) != 0; event.toolBar = (chromeFlags & nsIWebBrowserChrome.CHROME_TOOLBAR) != 0; for (int i = 0; i < visibilityWindowListeners.length; i++) { visibilityWindowListeners[i].show (event); } location = null; size = null; } } else { visible = false; for (int i = 0; i < visibilityWindowListeners.length; i++) { visibilityWindowListeners[i].hide (event); } } } return XPCOM.NS_OK; } int GetTitle (long /*int*/ aTitle) { return XPCOM.NS_OK; } int SetTitle (long /*int*/ aTitle) { if (titleListeners.length == 0) return XPCOM.NS_OK; TitleEvent event = new TitleEvent (browser); event.display = browser.getDisplay (); event.widget = browser; /* * To be consistent with other platforms the title event should * contain the page's url if the page does not contain a * tag. */ int length = XPCOM.strlen_PRUnichar (aTitle); if (length > 0) { char[] dest = new char[length]; XPCOM.memmove (dest, aTitle, length * 2); event.title = new String (dest); } else { event.title = getUrl (); } for (int i = 0; i < titleListeners.length; i++) { titleListeners[i].changed (event); } return XPCOM.NS_OK; } int GetSiteWindow (long /*int*/ aSiteWindow) { /* * This is expected to be an HWND on Windows, a GtkWidget* on GTK, and * a WindowPtr on OS X. This callback is invoked on Windows when the * print dialog is to be shown. If no handle is returned then no print * dialog is shown with XULRunner versions < 4. */ long /*int*/ siteWindow = delegate.getSiteWindow (); XPCOM.memmove (aSiteWindow, new long /*int*/[] {siteWindow}, C.PTR_SIZEOF); return XPCOM.NS_OK; } int Blur () { return XPCOM.NS_OK; } /* nsIWebBrowserChromeFocus */ int FocusNextElement () { /* * Bug in Mozilla embedding API. Mozilla takes back the focus after sending * this event. This prevents tabbing out of Mozilla. This behaviour can be reproduced * with the Mozilla application TestGtkEmbed. The workaround is to * send the traversal notification after this callback returns. */ browser.getDisplay ().asyncExec (new Runnable () { public void run () { if (browser.isDisposed ()) return; browser.traverse (SWT.TRAVERSE_TAB_NEXT); } }); return XPCOM.NS_OK; } int FocusPrevElement () { /* * Bug in Mozilla embedding API. Mozilla takes back the focus after sending * this event. This prevents tabbing out of Mozilla. This behaviour can be reproduced * with the Mozilla application TestGtkEmbed. The workaround is to * send the traversal notification after this callback returns. */ browser.getDisplay ().asyncExec (new Runnable () { public void run () { if (browser.isDisposed ()) return; browser.traverse (SWT.TRAVERSE_TAB_PREVIOUS); } }); return XPCOM.NS_OK; } /* nsIContextMenuListener */ int OnShowContextMenu (int aContextFlags, long /*int*/ aEvent, long /*int*/ aNode) { nsIDOMEvent domEvent = new nsIDOMEvent (aEvent); long /*int*/[] result = new long /*int*/[1]; int rc = domEvent.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID : nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_10_IID) :nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); int[] aScreenX = new int[1], aScreenY = new int[1]; nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]); rc = domMouseEvent.GetScreenX (aScreenX); if (rc != XPCOM.NS_OK) error (rc); rc = domMouseEvent.GetScreenY (aScreenY); if (rc != XPCOM.NS_OK) error (rc); domMouseEvent.Release (); Event event = new Event (); event.x = aScreenX[0]; event.y = aScreenY[0]; browser.notifyListeners (SWT.MenuDetect, event); if (!event.doit || browser.isDisposed ()) return XPCOM.NS_OK; Menu menu = browser.getMenu (); if (menu != null && !menu.isDisposed ()) { if (aScreenX[0] != event.x || aScreenY[0] != event.y) { menu.setLocation (event.x, event.y); } menu.setVisible (true); } return XPCOM.NS_OK; } /* nsIURIContentListener */ int OnStartURIOpen (long /*int*/ aURI, long /*int*/ retval) { if (isRetrievingBadCert) return XPCOM.NS_OK; authCount = 0; nsIURI location = new nsIURI (aURI); long /*int*/ aSpec = XPCOM.nsEmbedCString_new (); location.GetSpec (aSpec); int length = XPCOM.nsEmbedCString_Length (aSpec); long /*int*/ buffer = XPCOM.nsEmbedCString_get (aSpec); buffer = XPCOM.nsEmbedCString_get (aSpec); byte[] dest = new byte[length]; XPCOM.memmove (dest, buffer, length); XPCOM.nsEmbedCString_delete (aSpec); String value = new String (dest); /* * Navigating to "...aboutCertError.xhtml", or to "javascript:showSecuritySection()" when * the page "netError.xhtml" is showing, indicates that the last attempted page view had * an invalid certificate. When this happens, veto the current navigate and re-navigate * to the page with the bad certificate so that NotifyCertProblem will be invoked. */ if (value.indexOf ("aboutCertError.xhtml") != -1 || (isViewingErrorPage && value.indexOf ("javascript:showSecuritySection") != -1)) { //$NON-NLS-1$ //$NON-NLS-2$ XPCOM.memmove (retval, new boolean[] {true}); isRetrievingBadCert = true; setUrl (lastNavigateURL, (byte[])null, null); return XPCOM.NS_OK; } boolean doit = sendChangingEvent (value); XPCOM.memmove (retval, new boolean[] {!doit}); return XPCOM.NS_OK; } int DoContent (long /*int*/ aContentType, int aIsContentPreferred, long /*int*/ aRequest, long /*int*/ aContentHandler, long /*int*/ retval) { return XPCOM.NS_ERROR_NOT_IMPLEMENTED; } int IsPreferred (long /*int*/ aContentType, long /*int*/ aDesiredContentType, long /*int*/ retval) { boolean preferred = false; int size = XPCOM.strlen (aContentType); if (size > 0) { byte[] typeBytes = new byte[size + 1]; XPCOM.memmove (typeBytes, aContentType, size); String contentType = new String (typeBytes, 0, size); /* do not attempt to handle known problematic content types */ if (!contentType.equals (XPCOM.CONTENT_MAYBETEXT) && !contentType.equals (XPCOM.CONTENT_MULTIPART)) { /* determine whether browser can handle the content type */ long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; /* First try to use the nsIWebNavigationInfo if it's available (>= mozilla 1.8) */ byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_WEBNAVIGATIONINFO_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsIWebNavigationInfo.NS_IWEBNAVIGATIONINFO_IID, result); if (rc == XPCOM.NS_OK) { byte[] bytes = MozillaDelegate.wcsToMbcs (null, contentType, false); long /*int*/ typePtr = XPCOM.nsEmbedCString_new (bytes, bytes.length); nsIWebNavigationInfo info = new nsIWebNavigationInfo (result[0]); result[0] = 0; int[] isSupportedResult = new int[1]; /* PRUint32 */ rc = info.IsTypeSupported (typePtr, 0, isSupportedResult); if (rc != XPCOM.NS_OK) error (rc); info.Release (); XPCOM.nsEmbedCString_delete (typePtr); preferred = isSupportedResult[0] != 0; } else { /* nsIWebNavigationInfo is not available, so do the type lookup */ result[0] = 0; rc = serviceManager.GetService (XPCOM.NS_CATEGORYMANAGER_CID, nsICategoryManager.NS_ICATEGORYMANAGER_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsICategoryManager categoryManager = new nsICategoryManager (result[0]); result[0] = 0; byte[] categoryBytes = MozillaDelegate.wcsToMbcs (null, "Gecko-Content-Viewers", true); //$NON-NLS-1$ rc = categoryManager.GetCategoryEntry (categoryBytes, typeBytes, result); categoryManager.Release (); /* if no viewer for the content type is registered then rc == XPCOM.NS_ERROR_NOT_AVAILABLE */ preferred = rc == XPCOM.NS_OK; } serviceManager.Release (); } } XPCOM.memmove(retval, new boolean[] {preferred}); if (preferred) { XPCOM.memmove (aDesiredContentType, new long /*int*/[] {0}, C.PTR_SIZEOF); } return XPCOM.NS_OK; } int CanHandleContent (long /*int*/ aContentType, int aIsContentPreferred, long /*int*/ aDesiredContentType, long /*int*/ retval) { return XPCOM.NS_ERROR_NOT_IMPLEMENTED; } int GetLoadCookie (long /*int*/ aLoadCookie) { return XPCOM.NS_ERROR_NOT_IMPLEMENTED; } int SetLoadCookie (long /*int*/ aLoadCookie) { return XPCOM.NS_ERROR_NOT_IMPLEMENTED; } int GetParentContentListener (long /*int*/ aParentContentListener) { return XPCOM.NS_ERROR_NOT_IMPLEMENTED; } int SetParentContentListener (long /*int*/ aParentContentListener) { return XPCOM.NS_ERROR_NOT_IMPLEMENTED; } /* nsITooltipListener */ int OnShowTooltip (int aXCoords, int aYCoords, long /*int*/ aTipText) { int length = XPCOM.strlen_PRUnichar (aTipText); char[] dest = new char[length]; XPCOM.memmove (dest, aTipText, length * 2); String text = new String (dest); if (tip != null && !tip.isDisposed ()) tip.dispose (); Display display = browser.getDisplay (); Shell parent = browser.getShell (); tip = new Shell (parent, SWT.ON_TOP); tip.setLayout (new FillLayout()); Label label = new Label (tip, SWT.CENTER); label.setForeground (display.getSystemColor (SWT.COLOR_INFO_FOREGROUND)); label.setBackground (display.getSystemColor (SWT.COLOR_INFO_BACKGROUND)); label.setText (text); /* * Bug in Mozilla embedded API. Tooltip coordinates are wrong for * elements inside an inline frame (IFrame tag). The workaround is * to position the tooltip based on the mouse cursor location. */ Point point = display.getCursorLocation (); /* Assuming cursor is 21x21 because this is the size of * the arrow cursor on Windows */ point.y += 21; tip.setLocation (point); tip.pack (); tip.setVisible (true); return XPCOM.NS_OK; } int OnHideTooltip () { if (tip != null && !tip.isDisposed ()) tip.dispose (); tip = null; return XPCOM.NS_OK; } int HandleEvent (long /*int*/ event) { nsIDOMEvent domEvent = new nsIDOMEvent (event); long /*int*/ type = XPCOM.nsEmbedString_new (); int rc = domEvent.GetType (type); if (rc != XPCOM.NS_OK) error (rc); int length = XPCOM.nsEmbedString_Length (type); long /*int*/ buffer = XPCOM.nsEmbedString_get (type); char[] chars = new char[length]; XPCOM.memmove (chars, buffer, length * 2); String typeString = new String (chars); XPCOM.nsEmbedString_delete (type); if (XPCOM.DOMEVENT_UNLOAD.equals (typeString)) { long /*int*/[] result = new long /*int*/[1]; rc = domEvent.GetCurrentTarget (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]); unhookDOMListeners (target); target.Release (); return XPCOM.NS_OK; } if (XPCOM.DOMEVENT_FOCUS.equals (typeString)) { delegate.handleFocus (); return XPCOM.NS_OK; } if (XPCOM.DOMEVENT_KEYDOWN.equals (typeString)) { long /*int*/[] result = new long /*int*/[1]; rc = domEvent.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID : nsIDOMKeyEvent.NS_IDOMKEYEVENT_10_IID) : nsIDOMKeyEvent.NS_IDOMKEYEVENT_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]); result[0] = 0; int[] aKeyCode = new int[1]; /* PRUint32 */ rc = domKeyEvent.GetKeyCode (aKeyCode); if (rc != XPCOM.NS_OK) error (rc); int keyCode = translateKey (aKeyCode[0]); /* * if keyCode == lastKeyCode then either a repeating key like Shift * is being held or a key for which key events are not sent has been * pressed. In both of these cases a KeyDown should not be sent. */ if (keyCode != lastKeyCode) { lastKeyCode = keyCode; switch (keyCode) { case SWT.SHIFT: case SWT.CONTROL: case SWT.ALT: case SWT.CAPS_LOCK: case SWT.NUM_LOCK: case SWT.SCROLL_LOCK: case SWT.COMMAND: { /* keypress events will not be received for these keys, so send KeyDowns for them now */ int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ rc = domKeyEvent.GetAltKey (aAltKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetCtrlKey (aCtrlKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetShiftKey (aShiftKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetMetaKey (aMetaKey); if (rc != XPCOM.NS_OK) error (rc); Event keyEvent = new Event (); keyEvent.widget = browser; keyEvent.type = SWT.KeyDown; keyEvent.keyCode = keyCode; keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0); keyEvent.stateMask &= ~keyCode; /* remove current keydown if it's a state key */ browser.notifyListeners (keyEvent.type, keyEvent); if (!keyEvent.doit || browser.isDisposed ()) { domEvent.PreventDefault (); } break; } default: { /* * If the keydown has Meta (but not Meta+Ctrl) as a modifier then send a KeyDown event for it here * because a corresponding keypress event will not be received for it from the DOM. If the keydown * does not have Meta as a modifier, or has Meta+Ctrl as a modifier, then then do nothing here * because its KeyDown event will be sent from the keypress listener. */ int[] aMetaKey = new int[1]; /* PRBool */ rc = domKeyEvent.GetMetaKey (aMetaKey); if (rc != XPCOM.NS_OK) error (rc); if (aMetaKey[0] != 0) { int[] aCtrlKey = new int[1]; /* PRBool */ rc = domKeyEvent.GetCtrlKey (aCtrlKey); if (rc != XPCOM.NS_OK) error (rc); if (aCtrlKey[0] == 0) { int[] aAltKey = new int[1], aShiftKey = new int[1]; /* PRBool */ rc = domKeyEvent.GetAltKey (aAltKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetShiftKey (aShiftKey); if (rc != XPCOM.NS_OK) error (rc); Event keyEvent = new Event (); keyEvent.widget = browser; keyEvent.type = SWT.KeyDown; keyEvent.keyCode = lastKeyCode; keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0? SWT.CTRL : 0) | (aShiftKey[0] != 0? SWT.SHIFT : 0) | (aMetaKey[0] != 0? SWT.COMMAND : 0); browser.notifyListeners (keyEvent.type, keyEvent); if (!keyEvent.doit || browser.isDisposed ()) { domEvent.PreventDefault (); } } } } } } domKeyEvent.Release (); return XPCOM.NS_OK; } if (XPCOM.DOMEVENT_KEYPRESS.equals (typeString)) { /* * if keydown could not determine a keycode for this key then it's a * key for which key events are not sent (eg.- the Windows key) */ if (lastKeyCode == 0) return XPCOM.NS_OK; /* * On linux only, unexpected keypress events are received for some * modifier keys. The workaround is to ignore these events since * KeyDown events are sent for these keys in the keydown listener. */ switch (lastKeyCode) { case SWT.CAPS_LOCK: case SWT.NUM_LOCK: case SWT.SCROLL_LOCK: return XPCOM.NS_OK; } long /*int*/[] result = new long /*int*/[1]; rc = domEvent.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID : nsIDOMKeyEvent.NS_IDOMKEYEVENT_10_IID) : nsIDOMKeyEvent.NS_IDOMKEYEVENT_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]); result[0] = 0; int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ rc = domKeyEvent.GetAltKey (aAltKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetCtrlKey (aCtrlKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetShiftKey (aShiftKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetMetaKey (aMetaKey); if (rc != XPCOM.NS_OK) error (rc); int[] aCharCode = new int[1]; /* PRUint32 */ rc = domKeyEvent.GetCharCode (aCharCode); if (rc != XPCOM.NS_OK) error (rc); domKeyEvent.Release (); lastCharCode = aCharCode[0]; if (lastCharCode == 0) { switch (lastKeyCode) { case SWT.TAB: lastCharCode = SWT.TAB; break; case SWT.CR: lastCharCode = SWT.CR; break; case SWT.BS: lastCharCode = SWT.BS; break; case SWT.ESC: lastCharCode = SWT.ESC; break; case SWT.DEL: lastCharCode = SWT.DEL; break; } } if (aCtrlKey[0] != 0 && (0 <= lastCharCode && lastCharCode <= 0x7F)) { if ('a' <= lastCharCode && lastCharCode <= 'z') lastCharCode -= 'a' - 'A'; if (64 <= lastCharCode && lastCharCode <= 95) lastCharCode -= 64; } Event keyEvent = new Event (); keyEvent.widget = browser; keyEvent.type = SWT.KeyDown; keyEvent.keyCode = lastKeyCode; keyEvent.character = (char)lastCharCode; keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0); boolean doit = true; if (delegate.sendTraverse ()) { doit = sendKeyEvent (keyEvent); } else { browser.notifyListeners (keyEvent.type, keyEvent); doit = keyEvent.doit; } if (!doit || browser.isDisposed ()) { domEvent.PreventDefault (); } return XPCOM.NS_OK; } if (XPCOM.DOMEVENT_KEYUP.equals (typeString)) { long /*int*/[] result = new long /*int*/[1]; rc = domEvent.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMKeyEvent.NS_IDOMKEYEVENT_IID : nsIDOMKeyEvent.NS_IDOMKEYEVENT_10_IID) : nsIDOMKeyEvent.NS_IDOMKEYEVENT_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMKeyEvent domKeyEvent = new nsIDOMKeyEvent (result[0]); result[0] = 0; int[] aKeyCode = new int[1]; /* PRUint32 */ rc = domKeyEvent.GetKeyCode (aKeyCode); if (rc != XPCOM.NS_OK) error (rc); int keyCode = translateKey (aKeyCode[0]); if (keyCode == 0) { /* indicates a key for which key events are not sent */ domKeyEvent.Release (); return XPCOM.NS_OK; } if (keyCode != lastKeyCode) { /* keyup does not correspond to the last keydown */ lastKeyCode = keyCode; lastCharCode = 0; } int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ rc = domKeyEvent.GetAltKey (aAltKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetCtrlKey (aCtrlKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetShiftKey (aShiftKey); if (rc != XPCOM.NS_OK) error (rc); rc = domKeyEvent.GetMetaKey (aMetaKey); if (rc != XPCOM.NS_OK) error (rc); domKeyEvent.Release (); Event keyEvent = new Event (); keyEvent.widget = browser; keyEvent.type = SWT.KeyUp; keyEvent.keyCode = lastKeyCode; keyEvent.character = (char)lastCharCode; keyEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0); switch (lastKeyCode) { case SWT.SHIFT: case SWT.CONTROL: case SWT.ALT: case SWT.COMMAND: { keyEvent.stateMask |= lastKeyCode; } } browser.notifyListeners (keyEvent.type, keyEvent); if (!keyEvent.doit || browser.isDisposed ()) { domEvent.PreventDefault (); } lastKeyCode = lastCharCode = 0; return XPCOM.NS_OK; } /* mouse event */ long /*int*/[] result = new long /*int*/[1]; rc = domEvent.QueryInterface (IsPre_17 ? (IsPre_4 ? nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID : nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_10_IID) : nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_17_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]); result[0] = 0; /* * MouseOver and MouseOut events are fired any time the mouse enters or exits * any element within the Browser. To ensure that SWT events are only * fired for mouse movements into or out of the Browser, do not fire an * event if the element being exited (on MouseOver) or entered (on MouseExit) * is within the Browser. */ if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString) || XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) { rc = domMouseEvent.GetRelatedTarget (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] != 0) { new nsISupports (result[0]).Release (); domMouseEvent.Release (); return XPCOM.NS_OK; } } int[] aScreenX = new int[1], aScreenY = new int[1]; /* PRInt32 */ /* * The position of mouse events is received in screen-relative coordinates * in order to handle pages with frames, since frames express their event * coordinates relative to themselves rather than relative to their top- * level page. Convert screen-relative coordinates to be browser-relative. */ rc = domMouseEvent.GetScreenX (aScreenX); if (rc != XPCOM.NS_OK) error (rc); rc = domMouseEvent.GetScreenY (aScreenY); if (rc != XPCOM.NS_OK) error (rc); Point position = new Point (aScreenX[0], aScreenY[0]); position = browser.getDisplay ().map (null, browser, position); int[] aDetail = new int[1]; /* PRInt32 */ rc = domMouseEvent.GetDetail (aDetail); if (rc != XPCOM.NS_OK) error (rc); short[] aButton = new short[1]; /* PRUint16 */ rc = domMouseEvent.GetButton (aButton); if (rc != XPCOM.NS_OK) error (rc); int[] aAltKey = new int[1], aCtrlKey = new int[1], aShiftKey = new int[1], aMetaKey = new int[1]; /* PRBool */ rc = domMouseEvent.GetAltKey (aAltKey); if (rc != XPCOM.NS_OK) error (rc); rc = domMouseEvent.GetCtrlKey (aCtrlKey); if (rc != XPCOM.NS_OK) error (rc); rc = domMouseEvent.GetShiftKey (aShiftKey); if (rc != XPCOM.NS_OK) error (rc); rc = domMouseEvent.GetMetaKey (aMetaKey); if (rc != XPCOM.NS_OK) error (rc); domMouseEvent.Release (); Event mouseEvent = new Event (); mouseEvent.widget = browser; mouseEvent.x = position.x; mouseEvent.y = position.y; mouseEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0); if (XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) { delegate.handleMouseDown (); mouseEvent.type = SWT.MouseDown; mouseEvent.button = aButton[0] + 1; mouseEvent.count = aDetail[0]; } else if (XPCOM.DOMEVENT_MOUSEUP.equals (typeString)) { /* * Bug on OSX. For some reason multiple mouseup events come from the DOM * when button 3 is released on OSX. The first of these events has a count * detail and the others do not. The workaround is to not fire received * button 3 mouseup events that do not have a count since mouse events * without a click count are not valid. */ int button = aButton[0] + 1; int count = aDetail[0]; if (count == 0 && button == 3) return XPCOM.NS_OK; mouseEvent.type = SWT.MouseUp; mouseEvent.button = button; mouseEvent.count = count; } else if (XPCOM.DOMEVENT_MOUSEMOVE.equals (typeString)) { mouseEvent.type = SWT.MouseMove; } else if (XPCOM.DOMEVENT_MOUSEWHEEL.equals (typeString)) { mouseEvent.type = SWT.MouseWheel; mouseEvent.count = -aDetail[0]; } else if (XPCOM.DOMEVENT_MOUSEOVER.equals (typeString)) { mouseEvent.type = SWT.MouseEnter; } else if (XPCOM.DOMEVENT_MOUSEOUT.equals (typeString)) { mouseEvent.type = SWT.MouseExit; } else if (XPCOM.DOMEVENT_MOUSEDRAG.equals (typeString)) { mouseEvent.type = SWT.DragDetect; mouseEvent.button = aButton[0] + 1; switch (mouseEvent.button) { case 1: mouseEvent.stateMask |= SWT.BUTTON1; break; case 2: mouseEvent.stateMask |= SWT.BUTTON2; break; case 3: mouseEvent.stateMask |= SWT.BUTTON3; break; case 4: mouseEvent.stateMask |= SWT.BUTTON4; break; case 5: mouseEvent.stateMask |= SWT.BUTTON5; break; } } browser.notifyListeners (mouseEvent.type, mouseEvent); if (browser.isDisposed ()) return XPCOM.NS_OK; if (aDetail[0] == 2 && XPCOM.DOMEVENT_MOUSEDOWN.equals (typeString)) { mouseEvent = new Event (); mouseEvent.widget = browser; mouseEvent.x = position.x; mouseEvent.y = position.y; mouseEvent.stateMask = (aAltKey[0] != 0 ? SWT.ALT : 0) | (aCtrlKey[0] != 0 ? SWT.CTRL : 0) | (aShiftKey[0] != 0 ? SWT.SHIFT : 0) | (aMetaKey[0] != 0 ? SWT.COMMAND : 0); mouseEvent.type = SWT.MouseDoubleClick; mouseEvent.button = aButton[0] + 1; mouseEvent.count = aDetail[0]; browser.notifyListeners (mouseEvent.type, mouseEvent); } return XPCOM.NS_OK; } /* nsIBadCertListener2 */ int NotifyCertProblem (long /*int*/ socketInfo, long /*int*/ status, long /*int*/ targetSite, long /*int*/ _suppressError) { /* determine the host name and port */ int length = XPCOM.nsEmbedCString_Length (targetSite); long /*int*/ buffer = XPCOM.nsEmbedCString_get (targetSite); byte[] dest = new byte[length]; XPCOM.memmove (dest, buffer, length); final String urlPort = new String (dest); int index = urlPort.indexOf (':'); final String host = urlPort.substring (0,index); final int port = Integer.valueOf (urlPort.substring (index + 1)).intValue (); /* create text descriptions of the certificate problem(s) */ long /*int*/[] result = new long /*int*/[1]; nsISupports supports = new nsISupports (status); int rc = supports.QueryInterface (nsISSLStatus.NS_ISSLSTATUS_10_IID, result); if (rc != XPCOM.NS_OK) { rc = supports.QueryInterface (nsISSLStatus.NS_ISSLSTATUS_IID, result); if (rc != XPCOM.NS_OK) error (rc); } if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsISSLStatus sslStatus = new nsISSLStatus (result[0]); result[0] = 0; rc = sslStatus.GetServerCert (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); final nsIX509Cert cert = new nsIX509Cert (result[0]); result[0] = 0; String[] problems = new String[3]; int problemCount = 0, flags = 0; int[] intResult = new int[1]; rc = sslStatus.GetIsDomainMismatch (intResult); if (intResult[0] != 0) { long /*int*/ ptr = XPCOM.nsEmbedString_new (); rc = cert.GetCommonName (ptr); if (rc != XPCOM.NS_OK) SWT.error (rc); length = XPCOM.nsEmbedString_Length (ptr); buffer = XPCOM.nsEmbedString_get (ptr); char[] chars = new char[length]; XPCOM.memmove (chars, buffer, length * 2); String name = new String (chars); problems[problemCount++] = Compatibility.getMessage ("SWT_InvalidCert_InvalidName", new String[] {name}); //$NON-NLS-1$ flags |= nsICertOverrideService.ERROR_MISMATCH; XPCOM.nsEmbedString_delete (ptr); } intResult[0] = 0; rc = sslStatus.GetIsNotValidAtThisTime (intResult); if (intResult[0] != 0) { rc = cert.GetValidity (result); if (rc != XPCOM.NS_OK) SWT.error (rc); if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); nsIX509CertValidity validity = new nsIX509CertValidity(result[0]); result[0] = 0; long /*int*/ ptr = XPCOM.nsEmbedString_new (); rc = validity.GetNotBeforeGMT (ptr); if (rc != XPCOM.NS_OK) SWT.error (rc); length = XPCOM.nsEmbedString_Length (ptr); buffer = XPCOM.nsEmbedString_get (ptr); char[] chars = new char[length]; XPCOM.memmove (chars, buffer, length * 2); String notBefore = new String (chars); XPCOM.nsEmbedString_delete (ptr); ptr = XPCOM.nsEmbedString_new (); rc = validity.GetNotAfterGMT (ptr); if (rc != XPCOM.NS_OK) SWT.error (rc); length = XPCOM.nsEmbedString_Length (ptr); buffer = XPCOM.nsEmbedString_get (ptr); chars = new char[length]; XPCOM.memmove (chars, buffer, length * 2); String notAfter = new String (chars); XPCOM.nsEmbedString_delete (ptr); String range = notBefore + " - " + notAfter; //$NON-NLS-1$ problems[problemCount++] = Compatibility.getMessage ("SWT_InvalidCert_NotValid", new String[] {range}); //$NON-NLS-1$ flags |= nsICertOverrideService.ERROR_TIME; validity.Release (); } intResult[0] = 0; rc = sslStatus.GetIsUntrusted (intResult); if (intResult[0] != 0) { long /*int*/ ptr = XPCOM.nsEmbedString_new (); rc = cert.GetIssuerCommonName (ptr); if (rc != XPCOM.NS_OK) SWT.error (rc); length = XPCOM.nsEmbedString_Length (ptr); buffer = XPCOM.nsEmbedString_get (ptr); char[] chars = new char[length]; XPCOM.memmove (chars, buffer, length * 2); String name = new String (chars); problems[problemCount++] = Compatibility.getMessage ("SWT_InvalidCert_NotTrusted", new String[] {name}); //$NON-NLS-1$ flags |= nsICertOverrideService.ERROR_UNTRUSTED; XPCOM.nsEmbedString_delete (ptr); } intResult[0] = 0; sslStatus.Release (); /* * The invalid certificate dialog must be shown asynchronously because * NotifyCertProblem implementations cannot block. */ final int finalFlags = flags; final String[] finalProblems = new String[problemCount]; System.arraycopy (problems, 0, finalProblems, 0, problemCount); final String url = lastNavigateURL; browser.getDisplay().asyncExec(new Runnable() { public void run() { if (browser.isDisposed ()) return; if (url.equals (lastNavigateURL)) { String message = Compatibility.getMessage ("SWT_InvalidCert_Message", new String[] {urlPort}); //$NON-NLS-1$ if (new PromptDialog (browser.getShell ()).invalidCert (browser, message, finalProblems, cert)) { long /*int*/[] result = new long /*int*/[1]; int rc = XPCOM.NS_GetServiceManager (result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); nsIServiceManager serviceManager = new nsIServiceManager (result[0]); result[0] = 0; byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_CERTOVERRIDE_CONTRACTID, true); rc = serviceManager.GetServiceByContractID (aContractID, nsICertOverrideService.NS_ICERTOVERRIDESERVICE_IID, result); if (rc != XPCOM.NS_OK) error (rc); if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); serviceManager.Release (); nsICertOverrideService overrideService = new nsICertOverrideService (result[0]); result[0] = 0; byte[] hostBytes = MozillaDelegate.wcsToMbcs (null, host, false); long /*int*/ hostString = XPCOM.nsEmbedCString_new (hostBytes, hostBytes.length); rc = overrideService.RememberValidityOverride (hostString, port, cert.getAddress (), finalFlags, 1); navigate (badCertRequest); XPCOM.nsEmbedCString_delete (hostString); overrideService.Release (); } } cert.Release (); new nsISupports (badCertRequest).Release (); badCertRequest = 0; } }); XPCOM.memmove (_suppressError, new boolean[] {true}); return XPCOM.NS_OK; } }