blob: 8e829943e3251832c0d526982bdc1f3b65eee28f [file] [log] [blame]
# 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());
+ }
+}