| /******************************************************************************* |
| * Copyright (c) 2003, 2011 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 { |
| int /*long*/ embedHandle; |
| nsIWebBrowser webBrowser; |
| Object webBrowserObject; |
| MozillaDelegate delegate; |
| |
| /* Interfaces for this Mozilla embedding notification */ |
| XPCOMObject supports; |
| XPCOMObject weakReference; |
| XPCOMObject webProgressListener; |
| XPCOMObject webBrowserChrome; |
| XPCOMObject webBrowserChromeFocus; |
| XPCOMObject embeddingSiteWindow; |
| 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; |
| int /*long*/ request; |
| Point location, size; |
| boolean visible, 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, PerformedVersionCheck, XPCOMWasGlued, XPCOMInitWasGlued; |
| static String oldProxyHostFTP, oldProxyHostHTTP, oldProxyHostSSL; |
| static int oldProxyPortFTP = -1, oldProxyPortHTTP = -1, oldProxyPortSSL = -1, oldProxyType = -1; |
| static byte[] pathBytes_JSEvaluateUCScriptForPrincipals; |
| static byte[] pathBytes_NSFree; |
| |
| /* XULRunner detect constants */ |
| 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 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_CONTENTTYPE = "Content-Type"; //$NON-NLS-1 |
| static final String MIMETYPE_FORMURLENCODED = "application/x-www-form-urlencoded"; //$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 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 */ |
| |
| int /*long*/[] result = new int /*long*/[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 (nsIFile.NS_IFILE_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 */ |
| // int /*long*/ 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 int /*long*/[] {0} , C.PTR_SIZEOF); |
| // XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); |
| // XPCOM.XPCOMGlueLoadXULFunctions (ptr); |
| // C.memmove (result, functionLoad.function, C.PTR_SIZEOF); |
| // int /*long*/ 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; |
| |
| int /*long*/[] result = new int /*long*/[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; |
| int /*long*/[] result = new int /*long*/[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 */ |
| int /*long*/ domain = XPCOM.nsEmbedCString_new (); |
| int /*long*/ name = XPCOM.nsEmbedCString_new (); |
| int /*long*/ 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; |
| |
| int /*long*/[] result = new int /*long*/[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); |
| int /*long*/ 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); |
| int /*long*/ 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; |
| |
| int /*long*/[] result = new int /*long*/[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); |
| int /*long*/ 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; |
| } |
| }; |
| } |
| |
| public void create (Composite parent, int style) { |
| delegate = new MozillaDelegate (browser); |
| final Display display = parent.getDisplay (); |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| if (!Initialized) { |
| boolean initLoaded = false; |
| boolean isXULRunner = false; |
| |
| String greInitialized = System.getProperty (GRE_INITIALIZED); |
| if (TRUE.equals (greInitialized)) { |
| /* |
| * Another browser has already initialized xulrunner in this process, |
| * so just bind to it instead of trying to initialize a new one. |
| */ |
| Initialized = true; |
| } |
| |
| String 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 = delegate.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[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true); |
| int rc = XPCOMInit.XPCOMGlueStartup (path); |
| 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 */ |
| int /*long*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, XPCOM.MOZILLA_FIVE_HOME, true)); |
| if (ptr == 0) { |
| isXULRunner = false; |
| } else { |
| int length = C.strlen (ptr); |
| byte[] buffer = new byte[length]; |
| C.memmove (buffer, ptr, length); |
| mozillaPath = new String (MozillaDelegate.mbcsToWcs (null, buffer)); |
| /* |
| * 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 (); |
| path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true); |
| rc = XPCOMInit.XPCOMGlueStartup (path); |
| 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; |
| } |
| } |
| } |
| |
| 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 = delegate.getProfilePath (); |
| LocationProvider = new AppFileLocProvider (mozillaPath, profilePath, isXULRunner); |
| LocationProvider.AddRef (); |
| |
| /* write external.xpt to the file system if needed */ |
| initExternal (profilePath); |
| |
| /* load swt's mozilla/xulrunner library and invoke appropriate Init function */ |
| 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 = false; |
| String propertyString = System.getProperty (FACTORIES_REGISTERED); |
| if (TRUE.equals (propertyString)) { |
| factoriesRegistered = true; |
| } |
| |
| /* 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 */ |
| nsID NS_IWEBBROWSER_CID = new nsID ("F1EAC761-87E9-11d3-AF80-00A024FFC08C"); //$NON-NLS-1$ |
| rc = componentManager.CreateInstance (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) { |
| 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 = false; |
| String propertyString = System.getProperty (FACTORIES_REGISTERED); |
| if (TRUE.equals (propertyString)) { |
| factoriesRegistered = true; |
| } |
| |
| 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 (); |
| } |
| |
| /* |
| * 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 (); |
| } |
| result[0] = 0; |
| IsPre_1_9 = true; |
| |
| /* |
| * 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_1_8.NS_IDOCSHELL_IID, result); |
| if (rc == XPCOM.NS_OK && result[0] != 0) { /* 1.8 */ |
| 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 */ |
| IsPre_1_9 = false; |
| } |
| } |
| result[0] = 0; |
| interfaceRequestor.Release (); |
| componentRegistrar.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 (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_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 (); 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; |
| |
| int /*long*/[] result = new int /*long*/[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 int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| }; |
| |
| weakReference = new XPCOMObject (new int[] {2, 0, 0, 2}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return QueryReferent (args[0], args[1]);} |
| }; |
| |
| webProgressListener = new XPCOMObject (new int[] {2, 0, 0, 4, 6, 3, 4, 3}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return OnStateChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3]);} |
| public int /*long*/ method4 (int /*long*/[] args) {return OnProgressChange (args[0], args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4], (int)/*64*/args[5]);} |
| public int /*long*/ method5 (int /*long*/[] args) {return OnLocationChange (args[0], args[1], args[2]);} |
| public int /*long*/ method6 (int /*long*/[] args) {return OnStatusChange (args[0], args[1], (int)/*64*/args[2], args[3]);} |
| public int /*long*/ method7 (int /*long*/[] 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 int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return SetStatus ((int)/*64*/args[0], args[1]);} |
| public int /*long*/ method4 (int /*long*/[] args) {return GetWebBrowser (args[0]);} |
| public int /*long*/ method5 (int /*long*/[] args) {return SetWebBrowser (args[0]);} |
| public int /*long*/ method6 (int /*long*/[] args) {return GetChromeFlags (args[0]);} |
| public int /*long*/ method7 (int /*long*/[] args) {return SetChromeFlags ((int)/*64*/args[0]);} |
| public int /*long*/ method8 (int /*long*/[] args) {return DestroyBrowserWindow ();} |
| public int /*long*/ method9 (int /*long*/[] args) {return SizeBrowserTo ((int)/*64*/args[0], (int)/*64*/args[1]);} |
| public int /*long*/ method10 (int /*long*/[] args) {return ShowAsModal ();} |
| public int /*long*/ method11 (int /*long*/[] args) {return IsWindowModal (args[0]);} |
| public int /*long*/ method12 (int /*long*/[] args) {return ExitModalEventLoop ((int)/*64*/args[0]);} |
| }; |
| |
| webBrowserChromeFocus = new XPCOMObject (new int[] {2, 0, 0, 0, 0}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return FocusNextElement ();} |
| public int /*long*/ method4 (int /*long*/[] args) {return FocusPrevElement ();} |
| }; |
| |
| embeddingSiteWindow = new XPCOMObject (new int[] {2, 0, 0, 5, 5, 0, 1, 1, 1, 1, 1}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return SetDimensions ((int)/*64*/args[0], (int)/*64*/args[1], (int)/*64*/args[2], (int)/*64*/args[3], (int)/*64*/args[4]);} |
| public int /*long*/ method4 (int /*long*/[] args) {return GetDimensions ((int)/*64*/args[0], args[1], args[2], args[3], args[4]);} |
| public int /*long*/ method5 (int /*long*/[] args) {return SetFocus ();} |
| public int /*long*/ method6 (int /*long*/[] args) {return GetVisibility (args[0]);} |
| public int /*long*/ method7 (int /*long*/[] args) {return SetVisibility ((int)/*64*/args[0]);} |
| public int /*long*/ method8 (int /*long*/[] args) {return GetTitle (args[0]);} |
| public int /*long*/ method9 (int /*long*/[] args) {return SetTitle (args[0]);} |
| public int /*long*/ method10 (int /*long*/[] args) {return GetSiteWindow (args[0]);} |
| }; |
| |
| interfaceRequestor = new XPCOMObject (new int[] {2, 0, 0, 2} ){ |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return GetInterface (args[0], args[1]);} |
| }; |
| |
| supportsWeakReference = new XPCOMObject (new int[] {2, 0, 0, 1}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return GetWeakReference (args[0]);} |
| }; |
| |
| contextMenuListener = new XPCOMObject (new int[] {2, 0, 0, 3}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] 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 int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return OnStartURIOpen (args[0], args[1]);} |
| public int /*long*/ method4 (int /*long*/[] args) {return DoContent (args[0], (int)/*64*/args[1], args[2], args[3], args[4]);} |
| public int /*long*/ method5 (int /*long*/[] args) {return IsPreferred (args[0], args[1], args[2]);} |
| public int /*long*/ method6 (int /*long*/[] args) {return CanHandleContent (args[0], (int)/*64*/args[1], args[2], args[3]);} |
| public int /*long*/ method7 (int /*long*/[] args) {return GetLoadCookie (args[0]);} |
| public int /*long*/ method8 (int /*long*/[] args) {return SetLoadCookie (args[0]);} |
| public int /*long*/ method9 (int /*long*/[] args) {return GetParentContentListener (args[0]);} |
| public int /*long*/ method10 (int /*long*/[] args) {return SetParentContentListener (args[0]);} |
| }; |
| |
| tooltipListener = new XPCOMObject (new int[] {2, 0, 0, 3, 0}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return OnShowTooltip ((int)/*64*/args[0], (int)/*64*/args[1], args[2]);} |
| public int /*long*/ method4 (int /*long*/[] args) {return OnHideTooltip ();} |
| }; |
| |
| domEventListener = new XPCOMObject (new int[] {2, 0, 0, 1}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] args) {return HandleEvent (args[0]);} |
| }; |
| |
| badCertListener = new XPCOMObject (new int[] {2, 0, 0, 4}) { |
| public int /*long*/ method0 (int /*long*/[] args) {return QueryInterface (args[0], args[1]);} |
| public int /*long*/ method1 (int /*long*/[] args) {return AddRef ();} |
| public int /*long*/ method2 (int /*long*/[] args) {return Release ();} |
| public int /*long*/ method3 (int /*long*/[] 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 (webBrowserChrome != null) { |
| webBrowserChrome.dispose (); |
| webBrowserChrome = null; |
| } |
| if (webBrowserChromeFocus != null) { |
| webBrowserChromeFocus.dispose (); |
| webBrowserChromeFocus = null; |
| } |
| if (embeddingSiteWindow != null) { |
| embeddingSiteWindow.dispose (); |
| embeddingSiteWindow = 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. |
| */ |
| int /*long*/[] result = new int /*long*/[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); |
| |
| nsIServiceManager serviceManager = new nsIServiceManager (result[0]); |
| result[0] = 0; |
| nsIPrincipal principal = null; |
| byte[] aContractID = MozillaDelegate.wcsToMbcs (null, XPCOM.NS_SCRIPTSECURITYMANAGER_CONTRACTID, true); |
| rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager_1_9_1.NS_ISCRIPTSECURITYMANAGER_IID, result); |
| if (rc == XPCOM.NS_OK && result[0] != 0) { |
| nsIScriptSecurityManager_1_9_1 securityManager = new nsIScriptSecurityManager_1_9_1 (result[0]); |
| result[0] = 0; |
| rc = securityManager.GetSystemPrincipal (result); |
| if (rc != XPCOM.NS_OK) error (rc); |
| if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); |
| principal = new nsIPrincipal (result[0]); |
| result[0] = 0; |
| securityManager.Release (); |
| } else { |
| rc = serviceManager.GetServiceByContractID (aContractID, nsIScriptSecurityManager_1_9.NS_ISCRIPTSECURITYMANAGER_IID, result); |
| if (rc == XPCOM.NS_OK && result[0] != 0) { |
| nsIScriptSecurityManager_1_9 securityManager = new nsIScriptSecurityManager_1_9 (result[0]); |
| result[0] = 0; |
| rc = securityManager.GetSystemPrincipal (result); |
| if (rc != XPCOM.NS_OK) error (rc); |
| if (result[0] == 0) error (XPCOM.NS_ERROR_NULL_POINTER); |
| principal = new nsIPrincipal (result[0]); |
| result[0] = 0; |
| securityManager.Release (); |
| } |
| } |
| |
| if (principal != null) { |
| 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; |
| nsID scriptGlobalObjectNSID_1_9 = new nsID ("6afecd40-0b9a-4cfd-8c42-0f645cd91829"); /* nsIScriptGlobalObject */ //$NON-NLS-1$ |
| rc = interfaceRequestor.GetInterface (scriptGlobalObjectNSID_1_9, result); |
| if (!(rc == XPCOM.NS_OK && result[0] != 0)) { |
| result[0] = 0; |
| nsID scriptGlobalObjectNSID_1_9_2 = new nsID ("e9f3f2c1-2d94-4722-bbd4-2bf6fdf42f48"); /* nsIScriptGlobalObject */ //$NON-NLS-1$ |
| rc = interfaceRequestor.GetInterface (scriptGlobalObjectNSID_1_9_2, result); |
| } |
| interfaceRequestor.Release (); |
| |
| if (rc == XPCOM.NS_OK && result[0] != 0) { |
| int /*long*/ scriptGlobalObject = result[0]; |
| result[0] = 0; |
| rc = (int/*64*/)XPCOM.nsIScriptGlobalObject_EnsureScriptEnvironment (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */ |
| if (rc != XPCOM.NS_OK) error (rc); |
| int /*long*/ scriptContext = XPCOM.nsIScriptGlobalObject_GetScriptContext (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */ |
| int /*long*/ globalJSObject = XPCOM.nsIScriptGlobalObject_GetScriptGlobal (scriptGlobalObject, 2); /* nsIProgrammingLanguage.JAVASCRIPT */ |
| new nsISupports (scriptGlobalObject).Release (); |
| |
| if (scriptContext != 0 && globalJSObject != 0) { |
| /* ensure that the received nsIScriptContext implements the expected interface */ |
| nsID scriptContextNSID_1_9 = new nsID ("e7b9871d-3adc-4bf7-850d-7fb9554886bf"); /* nsIScriptContext */ //$NON-NLS-1$ |
| rc = new nsISupports (scriptContext).QueryInterface (scriptContextNSID_1_9, result); |
| if (!(rc == XPCOM.NS_OK && result[0] != 0)) { |
| result[0] = 0; |
| nsID scriptContextNSID_1_9_2 = new nsID ("87482b5e-e019-4df5-9bc2-b2a51b1f2d28"); /* nsIScriptContext */ //$NON-NLS-1$ |
| rc = new nsISupports (scriptContext).QueryInterface (scriptContextNSID_1_9_2, result); |
| } |
| |
| if (rc == XPCOM.NS_OK && result[0] != 0) { |
| new nsISupports (result[0]).Release (); |
| result[0] = 0; |
| |
| int /*long*/ nativeContext = XPCOM.nsIScriptContext_GetNativeContext (scriptContext); |
| if (nativeContext != 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 (nativeContext, result); |
| if (rc == XPCOM.NS_OK && result[0] != 0) { |
| int /*long*/ principals = result[0]; |
| result[0] = 0; |
| principal.Release (); |
| if (pathBytes_JSEvaluateUCScriptForPrincipals == null) { |
| String mozillaPath = getMozillaPath () + delegate.getJSLibraryName () + '\0'; |
| try { |
| pathBytes_JSEvaluateUCScriptForPrincipals = mozillaPath.getBytes ("UTF-8"); //$NON-NLS-1$ |
| } catch (UnsupportedEncodingException e) { |
| pathBytes_JSEvaluateUCScriptForPrincipals = mozillaPath.getBytes (); |
| } |
| } |
| |
| 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 (nativeContext); |
| if (rc != XPCOM.NS_OK) error (rc); |
| boolean success = XPCOM.JS_EvaluateUCScriptForPrincipals (pathBytes_JSEvaluateUCScriptForPrincipals, nativeContext, globalJSObject, principals, scriptChars, length, urlbytes, 0, result) != 0; |
| result[0] = 0; |
| rc = stack.Pop (result); |
| if (rc != XPCOM.NS_OK) error (rc); |
| stack.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 (int /*long*/ handle) { |
| return MozillaDelegate.findBrowser (handle); |
| } |
| |
| static Browser findBrowser (nsIDOMWindow aDOMWindow) { |
| int /*long*/[] result = new int /*long*/[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 */ |
| rc = aDOMWindow.GetTop (result); |
| if (rc != XPCOM.NS_OK) Mozilla.error (rc); |
| if (result[0] == 0) Mozilla.error (XPCOM.NS_NOINTERFACE); |
| int /*long*/ 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 (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_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; |
| rc = embeddingSiteWindow.GetSiteWindow (result); |
| 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; |
| |
| int /*long*/[] result = new int /*long*/[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 String getMozillaPath () { |
| if (LocationProvider != null) return LocationProvider.mozillaPath; |
| if (!Initialized) return ""; |
| |
| int /*long*/[] result = new int /*long*/[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, nsIDirectoryService.NS_IDIRECTORYSERVICE_IID, result); |
| if (rc != XPCOM.NS_OK) error (rc); |
| if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); |
| serviceManager.Release(); |
| |
| nsIDirectoryService directoryService = new nsIDirectoryService (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, nsIFile.NS_IFILE_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; |
| int /*long*/ path = XPCOM.nsEmbedCString_new (); |
| rc = mozillaDir.GetNativePath (path); |
| if (rc != XPCOM.NS_OK) error (rc); |
| int length = XPCOM.nsEmbedCString_Length (path); |
| int /*long*/ ptr = XPCOM.nsEmbedCString_get (path); |
| buffer = new byte[length]; |
| XPCOM.memmove (buffer, ptr, length); |
| XPCOM.nsEmbedCString_delete (path); |
| mozillaDir.Release (); |
| |
| return new String (MozillaDelegate.mbcsToWcs (null, buffer)) + SEPARATOR_OS; |
| } |
| |
| int getNextFunctionIndex () { |
| return NextJSFunctionIndex++; |
| } |
| |
| public String getText () { |
| int /*long*/[] result = new int /*long*/[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 (); |
| |
| int /*long*/ 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; |
| int /*long*/ string = XPCOM.nsEmbedString_new (); |
| rc = serializer.SerializeToString (document, string); |
| serializer.Release (); |
| |
| int length = XPCOM.nsEmbedString_Length (string); |
| int /*long*/ 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 () { |
| int /*long*/[] result = new int /*long*/[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 /*long*/[] aCurrentURI = new int /*long*/[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]); |
| int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); |
| rc = uri.GetSpec (aSpec); |
| if (rc != XPCOM.NS_OK) error (rc); |
| int length = XPCOM.nsEmbedCString_Length (aSpec); |
| int /*long*/ 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 ()), 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; |
| } |
| |
| String initDiscoverXULRunner () { |
| GREVersionRange range = new GREVersionRange (); |
| byte[] bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_LOWER, true); |
| int /*long*/ lower = C.malloc (bytes.length); |
| C.memmove (lower, bytes, bytes.length); |
| range.lower = lower; |
| range.lowerInclusive = LowerRangeInclusive; |
| |
| bytes = MozillaDelegate.wcsToMbcs (null, GRERANGE_UPPER, true); |
| int /*long*/ upper = C.malloc (bytes.length); |
| C.memmove (upper, bytes, bytes.length); |
| range.upper = upper; |
| range.upperInclusive = UpperRangeInclusive; |
| |
| int length = XPCOMInit.PATH_MAX; |
| int /*long*/ greBuffer = C.malloc (length); |
| int /*long*/ propertiesPtr = C.malloc (2 * C.PTR_SIZEOF); |
| int rc = XPCOMInit.GRE_GetGREPathWithProperties (range, 1, propertiesPtr, 0, greBuffer, length); |
| |
| /* |
| * A XULRunner was not found that supports wrapping of XPCOM handles as JavaXPCOM objects. |
| * Drop the lower version bound and try to detect an earlier XULRunner installation. |
| */ |
| if (rc != XPCOM.NS_OK) { |
| 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, propertiesPtr, 0, greBuffer, length); |
| } |
| C.free (lower); |
| C.free (upper); |
| C.free (propertiesPtr); |
| |
| 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) { |
| int /*long*/[] result = new int /*long*/[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; |
| 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); |
| } |
| 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[] category = MozillaDelegate.wcsToMbcs (null, "JavaScript global property", true); //$NON-NLS-1$ |
| byte[] entry = MozillaDelegate.wcsToMbcs (null, "external", true); //$NON-NLS-1$ |
| rc = categoryManager.AddCategoryEntry(category, entry, aContractID, 1, 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. |
| */ |
| 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 = isXULRunner ? new FilePickerFactory_1_8 () : 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 ()); |
| if (rc != XPCOM.NS_OK) { |
| browser.dispose (); |
| error (rc); |
| } |
| 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 */ |
| int /*long*/ ptr = C.getenv (MozillaDelegate.wcsToMbcs (null, XPCOM.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) { |
| int /*long*/[] result = new int /*long*/[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); |
| } |
| |
| nsILocalFile localFile = new nsILocalFile (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 */ |
| int /*long*/ ptr = C.malloc (size * 2); |
| C.memset (ptr, 0, size * 2); |
| nsDynamicFunctionLoad functionLoad = new nsDynamicFunctionLoad (); |
| byte[] bytes = MozillaDelegate.wcsToMbcs (null, "XRE_InitEmbedding", 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 int /*long*/[] {0} , C.PTR_SIZEOF); |
| XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); |
| XPCOM.XPCOMGlueLoadXULFunctions (ptr); |
| C.memmove (result, functionLoad.function, C.PTR_SIZEOF); |
| int /*long*/ 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); |
| } |
| rc = XPCOM.Call (functionPtr, localFile.getAddress (), localFile.getAddress (), LocationProvider.getAddress (), 0, 0); |
| if (rc == XPCOM.NS_OK) { |
| System.setProperty (XULRUNNER_PATH, mozillaPath); |
| } |
| } else { |
| 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) { |
| int /*long*/[] result = new int /*long*/[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); |
| String proxyPortString = System.getProperty (PROPERTY_PROXYPORT); |
| |
| int port = -1; |
| if (proxyPortString != null) { |
| try { |
| int value = Integer.valueOf (proxyPortString).intValue (); |
| if (0 <= value && value <= MAX_PORT) port = value; |
| } catch (NumberFormatException e) { |
| /* do nothing, java property has non-integer value */ |
| } |
| } |
| |
| 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) { |
| int /*long*/[] result = new int /*long*/[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 */ |
| int /*long*/ 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 int /*long*/[] {0} , C.PTR_SIZEOF); |
| XPCOM.memmove (ptr, functionLoad, XPCOM.nsDynamicFunctionLoad_sizeof ()); |
| XPCOM.XPCOMGlueLoadXULFunctions (ptr); |
| C.memmove (result, functionLoad.function, C.PTR_SIZEOF); |
| int /*long*/ 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 (delegate.needsSpinup ()) { |
| int /*long*/[] result = new int /*long*/[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); |
| } |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| 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 (); |
| |
| int /*long*/[] result = new int /*long*/[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); |
| } |
| byte[] path = MozillaDelegate.wcsToMbcs (null, mozillaPath, true); |
| int rc = XPCOM.XPCOMGlueStartup (path); |
| if (rc != XPCOM.NS_OK) { |
| browser.dispose (); |
| error (rc); |
| } |
| XPCOMWasGlued = true; |
| |
| /* |
| * Remove the trailing xpcom lib name from mozillaPath because the |
| * Mozilla.initialize and NS_InitXPCOM2 invocations require a directory name only. |
| */ |
| return mozillaPath.substring (0, mozillaPath.lastIndexOf (SEPARATOR_OS)); |
| } |
| |
| public boolean isBackEnabled () { |
| int /*long*/[] result = new int /*long*/[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 () { |
| int /*long*/[] result = new int /*long*/[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 " + 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; |
| } |
| |
| int rc = webBrowser.RemoveWebBrowserListener (weakReference.getAddress (), nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_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 (); |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| 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 () { |
| int /*long*/[] result = new int /*long*/[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 () { |
| int /*long*/[] result = new int /*long*/[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 onResize () { |
| Rectangle rect = browser.getClientArea (); |
| int width = Math.max (1, rect.width); |
| int height = Math.max (1, rect.height); |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| int 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; |
| |
| int /*long*/[] result = new int /*long*/[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); |
| } |
| |
| 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 (); |
| |
| int /*long*/[] result = new int /*long*/[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$ |
| int /*long*/ aContentCharset = XPCOM.nsEmbedCString_new (contentCharsetBuffer, contentCharsetBuffer.length); |
| byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", false); // $NON-NLS-1$ |
| int /*long*/ 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); |
| } |
| int /*long*/ 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) { |
| htmlBytes = null; |
| |
| int /*long*/[] result = new int /*long*/[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 */ |
| byte[] bytes = MozillaDelegate.wcsToMbcs (null, postData, false); |
| dataStream = new InputStream (bytes); |
| dataStream.AddRef (); |
| postDataStream = new nsIMIMEInputStream (result[0]); |
| rc = postDataStream.SetData (dataStream.getAddress ()); |
| if (rc != XPCOM.NS_OK) error (rc); |
| rc = postDataStream.SetAddContentLength (1); |
| if (rc != XPCOM.NS_OK) error (rc); |
| 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; |
| |
| int /*long*/[] result = new int /*long*/[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); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_UNLOAD); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDOWN); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEUP); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEMOVE); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEWHEEL); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEDRAG); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 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); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_MOUSEOUT); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| } |
| |
| string = new nsEmbedString (XPCOM.DOMEVENT_KEYDOWN); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_KEYPRESS); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| string = new nsEmbedString (XPCOM.DOMEVENT_KEYUP); |
| target.AddEventListener (string.getAddress (), domEventListener.getAddress (), 0); |
| string.dispose (); |
| } |
| |
| void unhookDOMListeners () { |
| int /*long*/[] result = new int /*long*/[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 (nsIDOMEventTarget.NS_IDOMEVENTTARGET_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 (nsIDOMEventTarget.NS_IDOMEVENTTARGET_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 (int /*long*/ riid, int /*long*/ 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 int /*long*/[] {supports.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIWeakReference.NS_IWEAKREFERENCE_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIWebProgressListener.NS_IWEBPROGRESSLISTENER_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {webProgressListener.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIWebBrowserChrome.NS_IWEBBROWSERCHROME_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChrome.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIWebBrowserChromeFocus.NS_IWEBBROWSERCHROMEFOCUS_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {webBrowserChromeFocus.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIEmbeddingSiteWindow.NS_IEMBEDDINGSITEWINDOW_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {embeddingSiteWindow.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {interfaceRequestor.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsISupportsWeakReference.NS_ISUPPORTSWEAKREFERENCE_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {supportsWeakReference.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIContextMenuListener.NS_ICONTEXTMENULISTENER_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {contextMenuListener.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIURIContentListener.NS_IURICONTENTLISTENER_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {uriContentListener.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsITooltipListener.NS_ITOOLTIPLISTENER_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {tooltipListener.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| if (guid.Equals (nsIBadCertListener2.NS_IBADCERTLISTENER2_IID)) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {badCertListener.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| XPCOM.memmove (ppvObject, new int /*long*/[] {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 (int /*long*/ riid, int /*long*/ ppvObject) { |
| return QueryInterface (riid, ppvObject); |
| } |
| |
| /* nsIInterfaceRequestor */ |
| |
| int GetInterface (int /*long*/ riid, int /*long*/ 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_IID)) { |
| int /*long*/[] aContentDOMWindow = new int /*long*/[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 (int /*long*/ ppvObject) { |
| XPCOM.memmove (ppvObject, new int /*long*/[] {weakReference.getAddress ()}, C.PTR_SIZEOF); |
| AddRef (); |
| return XPCOM.NS_OK; |
| } |
| |
| /* nsIWebProgressListener */ |
| |
| int OnStateChange (int /*long*/ aWebProgress, int /*long*/ 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 to a site with an invalid |
| * certificate, no STATE_IS_DOCUMENT state transitions are received for the |
| * new location, and an immediate attempt is made to show the invalid |
| * certificate error. However our invalid certificate handler must know |
| * the site with the invalid certificate, not the site that redirected to |
| * it. The only opportunity to get this site before our invalid certificate |
| * handler is invoked is in the subsequent STATE_START | STATE_IS_REQUEST |
| * transition. When this comes, if the request's name appears to be a |
| * url then take this to be the new site, in case our invalid certificate |
| * handler is about to be invoked. |
| * |
| * 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); |
| int /*long*/ name = XPCOM.nsEmbedCString_new (); |
| int rc = request.GetName (name); |
| if (rc == XPCOM.NS_OK) { |
| int length = XPCOM.nsEmbedCString_Length (name); |
| int /*long*/ buffer = XPCOM.nsEmbedCString_get (name); |
| byte[] bytes = new byte[length]; |
| XPCOM.memmove (bytes, buffer, length); |
| String value = new String (bytes); |
| if (value.indexOf (":/") != -1) lastNavigateURL = value; //$NON-NLS-1$ |
| } |
| XPCOM.nsEmbedCString_delete (name); |
| } |
| |
| if ((aStateFlags & nsIWebProgressListener.STATE_IS_DOCUMENT) == 0) return XPCOM.NS_OK; |
| if ((aStateFlags & nsIWebProgressListener.STATE_START) != 0) { |
| int /*long*/[] result = new int /*long*/[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) { |
| isRetrievingBadCert = false; |
| nsIRequest request = new nsIRequest (aRequest); |
| int 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 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. |
| */ |
| int /*long*/[] result = new int /*long*/[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 (nsIDOMEventTarget.NS_IDOMEVENTTARGET_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; |
| hookDOMListeners (target, isTop); |
| target.Release (); |
| |
| /* |
| * 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); |
| int /*long*/ name = XPCOM.nsEmbedCString_new (); |
| rc = req.GetName (name); |
| if (rc != XPCOM.NS_OK) error (rc); |
| int length = XPCOM.nsEmbedCString_Length (name); |
| int /*long*/ 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); |
| } |
| int /*long*/ 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$ |
| int /*long*/ 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; |
| |
| int /*long*/ ptr = C.malloc (htmlBytes.length); |
| XPCOM.memmove (ptr, htmlBytes, htmlBytes.length); |
| int pageSize = 8192; |
| int pageCount = htmlBytes.length / pageSize + 1; |
| int /*long*/ 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; |
| |
| 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 (nsIDOMEventTarget.NS_IDOMEVENTTARGET_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; |
| hookDOMListeners (target, isTop); |
| target.Release (); |
| } else { |
| registerFunctionsOnState = 0; |
| } |
| } |
| domWindow.Release (); |
| |
| /* |
| * 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 (updateLastNavigateUrl) { |
| updateLastNavigateUrl = false; |
| int /*long*/[] result = new int /*long*/[1]; |
| nsIRequest request = new nsIRequest (aRequest); |
| |
| int 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; |
| int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); |
| rc = uri.GetSpec (aSpec); |
| if (rc != XPCOM.NS_OK) error (rc); |
| int length = XPCOM.nsEmbedCString_Length (aSpec); |
| int /*long*/ 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. |
| */ |
| int /*long*/[] result = new int /*long*/[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 (nsIDOMEventTarget.NS_IDOMEVENTTARGET_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; |
| hookDOMListeners (target, isTop); |
| target.Release (); |
| |
| /* |
| * 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 (int /*long*/ aWebProgress, int /*long*/ 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 (int /*long*/ aWebProgress, int /*long*/ aRequest, int /*long*/ aLocation) { |
| /* |
| * 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); |
| int /*long*/[] aDOMWindow = new int /*long*/[1]; |
| int rc = webProgress.GetDOMWindow (aDOMWindow); |
| if (rc != XPCOM.NS_OK) error (rc); |
| if (aDOMWindow[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); |
| |
| nsIDOMWindow domWindow = new nsIDOMWindow (aDOMWindow[0]); |
| int /*long*/[] aTop = new int /*long*/[1]; |
| rc = domWindow.GetTop (aTop); |
| if (rc != XPCOM.NS_OK) error (rc); |
| if (aTop[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); |
| domWindow.Release (); |
| |
| nsIDOMWindow topWindow = new nsIDOMWindow (aTop[0]); |
| topWindow.Release (); |
| |
| nsIURI location = new nsIURI (aLocation); |
| int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); |
| location.GetSpec (aSpec); |
| int length = XPCOM.nsEmbedCString_Length (aSpec); |
| int /*long*/ 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 (int /*long*/ aWebProgress, int /*long*/ aRequest, int aStatus, int /*long*/ 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 (int /*long*/ aWebProgress, int /*long*/ aRequest, int state) { |
| return XPCOM.NS_OK; |
| } |
| |
| /* nsIWebBrowserChrome */ |
| |
| int SetStatus (int statusType, int /*long*/ 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 (int /*long*/ aWebBrowser) { |
| int /*long*/[] ret = new int /*long*/[1]; |
| if (webBrowser != null) { |
| webBrowser.AddRef (); |
| ret[0] = webBrowser.getAddress (); |
| } |
| XPCOM.memmove (aWebBrowser, ret, C.PTR_SIZEOF); |
| return XPCOM.NS_OK; |
| } |
| |
| int SetWebBrowser (int /*long*/ aWebBrowser) { |
| if (webBrowser != null) webBrowser.Release (); |
| webBrowser = aWebBrowser != 0 ? new nsIWebBrowser (aWebBrowser) : null; |
| return XPCOM.NS_OK; |
| } |
| |
| int GetChromeFlags (int /*long*/ 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 () { |
| int /*long*/[] result = new int /*long*/[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 (int /*long*/ retval) { |
| int result = (chromeFlags & nsIWebBrowserChrome.CHROME_MODAL) != 0 ? 1 : 0; |
| XPCOM.memmove (retval, new int[] {result}, 4); /* PRBool */ |
| 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, int /*long*/ x, int /*long*/ y, int /*long*/ cx, int /*long*/ 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 () { |
| int /*long*/[] result = new int /*long*/[1]; |
| int 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 (int /*long*/ aVisibility) { |
| boolean visible = browser.isVisible () && !browser.getShell ().getMinimized (); |
| XPCOM.memmove (aVisibility, new int[] {visible ? 1 : 0}, 4); /* PRBool */ |
| 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 (int /*long*/ aTitle) { |
| return XPCOM.NS_OK; |
| } |
| |
| int SetTitle (int /*long*/ 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 <title> |
| * 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 (int /*long*/ aSiteWindow) { |
| /* |
| * Note. The handle is expected to be an HWND on Windows and |
| * a GtkWidget* on GTK. This callback is invoked on Windows |
| * when the javascript window.print is invoked and the print |
| * dialog comes up. If no handle is returned, the print dialog |
| * does not come up on this platform. |
| */ |
| XPCOM.memmove (aSiteWindow, new int /*long*/[] {embedHandle}, C.PTR_SIZEOF); |
| 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, int /*long*/ aEvent, int /*long*/ aNode) { |
| nsIDOMEvent domEvent = new nsIDOMEvent (aEvent); |
| int /*long*/[] result = new int /*long*/[1]; |
| int rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_IID, result); |
| if (rc != XPCOM.NS_OK) error (rc); |
| if (result[0] == 0) error (XPCOM.NS_NOINTERFACE); |
| |
| nsIDOMMouseEvent domMouseEvent = new nsIDOMMouseEvent (result[0]); |
| int[] aScreenX = new int[1], aScreenY = new int[1]; |
| 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 (int /*long*/ aURI, int /*long*/ retval) { |
| if (isRetrievingBadCert) return XPCOM.NS_OK; |
| authCount = 0; |
| |
| nsIURI location = new nsIURI (aURI); |
| int /*long*/ aSpec = XPCOM.nsEmbedCString_new (); |
| location.GetSpec (aSpec); |
| int length = XPCOM.nsEmbedCString_Length (aSpec); |
| int /*long*/ 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 int[] {1}, 4); /* PRBool */ |
| isRetrievingBadCert = true; |
| setUrl (lastNavigateURL, null, null); |
| return XPCOM.NS_OK; |
| } |
| isViewingErrorPage = value.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 (!value.startsWith (PREFIX_JAVASCRIPT)) { |
| if (locationListeners.length > 0) { |
| LocationEvent event = new LocationEvent (browser); |
| event.display = browser.getDisplay(); |
| event.widget = browser; |
| event.location = value; |
| /* |
| * 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.doit = doit; |
| for (int i = 0; i < locationListeners.length; i++) { |
| locationListeners[i].changing (event); |
| } |
| doit = event.doit && !browser.isDisposed(); |
| } |
| |
| if (doit) { |
| if (jsEnabledChanged) { |
| jsEnabledChanged = false; |
| |
| int /*long*/[] result = new int /*long*/[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 = value; |
| } |
| } |
| } |
| XPCOM.memmove (retval, new int[] {doit ? 0 : 1}, 4); /* PRBool */ |
| return XPCOM.NS_OK; |
| } |
| |
| int DoContent (int /*long*/ aContentType, int aIsContentPreferred, int /*long*/ aRequest, int /*long*/ aContentHandler, int /*long*/ retval) { |
| return XPCOM.NS_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| int IsPreferred (int /*long*/ aContentType, int /*long*/ aDesiredContentType, int /*long*/ 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 */ |
| int /*long*/[] result = new int /*long*/[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); |
| int /*long*/ 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 int[] {preferred ? 1 : 0}, 4); /* PRBool */ |
| if (preferred) { |
| XPCOM.memmove (aDesiredContentType, new int /*long*/[] {0}, C.PTR_SIZEOF); |
| } |
| return XPCOM.NS_OK; |
| } |
| |
| int CanHandleContent (int /*long*/ aContentType, int aIsContentPreferred, int /*long*/ aDesiredContentType, int /*long*/ retval) { |
| return XPCOM.NS_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| int GetLoadCookie (int /*long*/ aLoadCookie) { |
| return XPCOM.NS_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| int SetLoadCookie (int /*long*/ aLoadCookie) { |
| return XPCOM.NS_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| int GetParentContentListener (int /*long*/ aParentContentListener) { |
| return XPCOM.NS_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| int SetParentContentListener (int /*long*/ aParentContentListener) { |
| return XPCOM.NS_ERROR_NOT_IMPLEMENTED; |
| } |
| |
| /* nsITooltipListener */ |
| |
| int OnShowTooltip (int aXCoords, int aYCoords, int /*long*/ 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; |
| } |
| |
| /* nsIDOMEventListener */ |
| |
| int HandleEvent (int /*long*/ event) { |
| nsIDOMEvent domEvent = new nsIDOMEvent (event); |
| |
| int /*long*/ type = XPCOM.nsEmbedString_new (); |
| int rc = domEvent.GetType (type); |
| if (rc != XPCOM.NS_OK) error (rc); |
| int length = XPCOM.nsEmbedString_Length (type); |
| int /*long*/ 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)) { |
| int /*long*/[] result = new int /*long*/[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)) { |
| int /*long*/[] result = new int /*long*/[1]; |
| rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_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; |
| } |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_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); |
| domKeyEvent.Release (); |
| |
| int[] aCharCode = new int[1]; /* PRUint32 */ |
| rc = domKeyEvent.GetCharCode (aCharCode); |
| if (rc != XPCOM.NS_OK) error (rc); |
| 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)) { |
| int /*long*/[] result = new int /*long*/[1]; |
| rc = domEvent.QueryInterface (nsIDOMKeyEvent.NS_IDOMKEYEVENT_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 */ |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| rc = domEvent.QueryInterface (nsIDOMMouseEvent.NS_IDOMMOUSEEVENT_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 (int /*long*/ socketInfo, int /*long*/ status, int /*long*/ targetSite, int /*long*/ _suppressError) { |
| /* determine the host name and port */ |
| int length = XPCOM.nsEmbedCString_Length (targetSite); |
| int /*long*/ 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) */ |
| |
| int /*long*/[] result = new int /*long*/[1]; |
| nsISupports supports = new nsISupports (status); |
| int 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) { |
| int /*long*/ 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; |
| |
| int /*long*/ 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) { |
| int /*long*/ 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)) return; /* user has navigated elsewhere */ |
| |
| String message = Compatibility.getMessage ("SWT_InvalidCert_Message", new String[] {urlPort}); //$NON-NLS-1$ |
| if (new PromptDialog (browser.getShell ()).invalidCert (browser, message, finalProblems, cert)) { |
| int /*long*/[] result = new int /*long*/[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); |
| int /*long*/ hostString = XPCOM.nsEmbedCString_new (hostBytes, hostBytes.length); |
| rc = overrideService.RememberValidityOverride (hostString, port, cert.getAddress (), finalFlags, 1); |
| browser.setUrl (url); |
| XPCOM.nsEmbedCString_delete (hostString); |
| overrideService.Release (); |
| } |
| cert.Release (); |
| } |
| }); |
| |
| C.memmove (_suppressError, new int[] {1}, 4); /* PRInt32 */ |
| return XPCOM.NS_OK; |
| } |
| |
| } |