| # Patch by Grant Gayed |
| # https://bugs.eclipse.org/bugs/show_bug.cgi?id=268651#c18 |
| # https://bugs.eclipse.org/bugs/attachment.cgi?id=130751 |
| Index: Eclipse SWT Mozilla/common/org/eclipse/swt/browser/Mozilla.java |
| =================================================================== |
| RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/browser/Mozilla.java,v |
| retrieving revision 1.105.2.3 |
| diff -u -r1.105.2.3 Mozilla.java |
| --- src/org/eclipse/swt/browser/Mozilla.java 21 Aug 2008 16:02:30 -00001.105.2.3 |
| +++ src/org/eclipse/swt/browser/Mozilla.java 2 Apr 2009 19:15:06 -0000 |
| @@ -47,6 +47,7 @@ |
| Shell tip = null; |
| Listener listener; |
| Vector unhookedDOMWindows = new Vector (); |
| + byte[] htmlBytes; |
| |
| static nsIAppShell AppShell; |
| static AppFileLocProvider LocationProvider; |
| @@ -1130,21 +1131,21 @@ |
| * Once the client does a proper navigate with either setUrl() or setText() then resume as |
| * normal. The Mozilla bug for this is https://bugzilla.mozilla.org/show_bug.cgi?id=415789. |
| */ |
| - awaitingNavigate = true; |
| - rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); |
| - if (rc != XPCOM.NS_OK) { |
| - browser.dispose (); |
| - error (rc); |
| - } |
| - if (result[0] == 0) { |
| - browser.dispose (); |
| - error (XPCOM.NS_ERROR_NO_INTERFACE); |
| - } |
| - nsIWebNavigation webNavigation = new nsIWebNavigation (result[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); |
| - webNavigation.Release (); |
| +// awaitingNavigate = true; |
| +// rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result); |
| +// if (rc != XPCOM.NS_OK) { |
| +// browser.dispose (); |
| +// error (rc); |
| +// } |
| +// if (result[0] == 0) { |
| +// browser.dispose (); |
| +// error (XPCOM.NS_ERROR_NO_INTERFACE); |
| +// } |
| +// nsIWebNavigation webNavigation = new nsIWebNavigation (result[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); |
| +// webNavigation.Release (); |
| } |
| } |
| result[0] = 0; |
| @@ -1223,6 +1224,7 @@ |
| } |
| |
| public boolean back () { |
| + htmlBytes = null; |
| if (awaitingNavigate) return false; |
| |
| long /*int*/[] result = new long /*int*/[1]; |
| @@ -1425,6 +1427,7 @@ |
| } |
| |
| public boolean forward () { |
| + htmlBytes = null; |
| if (awaitingNavigate) return false; |
| |
| long /*int*/[] result = new long /*int*/[1]; |
| @@ -1635,6 +1638,7 @@ |
| webBrowser.Release (); |
| webBrowser = null; |
| webBrowserObject = null; |
| + htmlBytes = null; |
| |
| if (tip != null && !tip.isDisposed ()) tip.dispose (); |
| tip = null; |
| @@ -1696,6 +1700,7 @@ |
| } |
| |
| public void refresh () { |
| + htmlBytes = null; |
| if (awaitingNavigate) return; |
| |
| long /*int*/[] result = new long /*int*/[1]; |
| @@ -1817,11 +1822,45 @@ |
| } else { |
| result[0] = 0; |
| 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]); |
| - rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0); |
| - docShell.Release (); |
| + if (rc == XPCOM.NS_OK) { |
| + if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); |
| + nsIDocShell docShell = new nsIDocShell (result[0]); |
| + rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType, aContentCharset, 0); |
| + docShell.Release (); |
| + } else { |
| + result[0] = 0; |
| + rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result); |
| + if (rc == XPCOM.NS_OK) { |
| + if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE); |
| + /* |
| + * 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; |
| + 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[] uriChars = new char[ABOUT_BLANK.length () + 1]; |
| + ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uriChars, 0); |
| + rc = webNavigation.LoadURI (uriChars, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0); |
| + webNavigation.Release (); |
| + } |
| + } |
| } |
| } |
| if (rc != XPCOM.NS_OK) error (rc); |
| @@ -1836,6 +1875,7 @@ |
| } |
| |
| public boolean setUrl (String url) { |
| + htmlBytes = null; |
| awaitingNavigate = false; |
| |
| long /*int*/[] result = new long /*int*/[1]; |
| @@ -1852,6 +1892,7 @@ |
| } |
| |
| public void stop () { |
| + htmlBytes = null; |
| if (awaitingNavigate) return; |
| |
| long /*int*/[] result = new long /*int*/[1]; |
| @@ -2174,6 +2215,108 @@ |
| unhookedDOMWindows.remove (ptrObject); |
| new nsISupports (ptrObject.value).Release (); |
| } |
| + |
| + /* |
| + * 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; |
| + /* |
| + * Note. Mozilla ignores LINK tags used to load CSS stylesheets |
| + * when the URI protocol for the nsInputStreamChannel |
| + * is about:blank. The fix is to specify the file protocol. |
| + */ |
| + byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, 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", true); // $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); |
| + 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; |
| + |
| + 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 (); |
| + } |
| + } |
| domWindow.Release (); |
| |
| /* |
| Index: Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java |
| =================================================================== |
| RCS file: Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java |
| diff -N Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java |
| --- /dev/null 1 Jan 1970 00:00:00 -0000 |
| +++ src/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java 1 Jan 1970 00:00:00 -0000 |
| @@ -0,0 +1,55 @@ |
| +/* ***** BEGIN LICENSE BLOCK ***** |
| + * Version: MPL 1.1 |
| + * |
| + * The contents of this file are subject to the Mozilla Public License Version |
| + * 1.1 (the "License"); you may not use this file except in compliance with |
| + * the License. You may obtain a copy of the License at |
| + * http://www.mozilla.org/MPL/ |
| + * |
| + * Software distributed under the License is distributed on an "AS IS" basis, |
| + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| + * for the specific language governing rights and limitations under the |
| + * License. |
| + * |
| + * The Original Code is Mozilla Communicator client code, released March 31, 1998. |
| + * |
| + * The Initial Developer of the Original Code is |
| + * Netscape Communications Corporation. |
| + * Portions created by Netscape are Copyright (C) 1998-1999 |
| + * Netscape Communications Corporation. All Rights Reserved. |
| + * |
| + * Contributor(s): |
| + * |
| + * IBM |
| + * - Binding to permit interfacing between Mozilla and SWT |
| + * - Copyright (C) 2003, 2009 IBM Corp. All Rights Reserved. |
| + * |
| + * ***** END LICENSE BLOCK ***** */ |
| +package org.eclipse.swt.internal.mozilla; |
| + |
| +public class nsIWebBrowserStream extends nsISupports { |
| + |
| + static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 3; |
| + |
| + public static final String NS_IWEBBROWSERSTREAM_IID_STR = |
| + "86d02f0e-219b-4cfc-9c88-bd98d2cce0b8"; |
| + |
| + public static final nsID NS_IWEBBROWSERSTREAM_IID = |
| + new nsID(NS_IWEBBROWSERSTREAM_IID_STR); |
| + |
| + public nsIWebBrowserStream(int /*long*/ address) { |
| + super(address); |
| + } |
| + |
| + public int OpenStream(int /*long*/ aBaseURI, int /*long*/ aContentType) { |
| + return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), aBaseURI, aContentType); |
| + } |
| + |
| + public int AppendToStream(int /*long*/ aData, int aLen) { |
| + return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aData, aLen); |
| + } |
| + |
| + public int CloseStream() { |
| + return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 3, getAddress()); |
| + } |
| +} |