43ecf62
### Eclipse Workspace Patch 1.0
43ecf62
#P org.eclipse.swt
43ecf62
Index: Eclipse SWT Mozilla/common/org/eclipse/swt/browser/Mozilla.java
43ecf62
===================================================================
43ecf62
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/browser/Mozilla.java,v
43ecf62
retrieving revision 1.105.2.3
43ecf62
diff -u -r1.105.2.3 Mozilla.java
43ecf62
--- Eclipse SWT Mozilla/common/org/eclipse/swt/browser/Mozilla.java	21 Aug 2008 16:02:30 -0000	1.105.2.3
43ecf62
+++ Eclipse SWT Mozilla/common/org/eclipse/swt/browser/Mozilla.java	2 Apr 2009 19:15:06 -0000
43ecf62
@@ -47,6 +47,7 @@
43ecf62
 	Shell tip = null;
43ecf62
 	Listener listener;
43ecf62
 	Vector unhookedDOMWindows = new Vector ();
43ecf62
+	byte[] htmlBytes;
43ecf62
 
43ecf62
 	static nsIAppShell AppShell;
43ecf62
 	static AppFileLocProvider LocationProvider;
43ecf62
@@ -1168,21 +1169,21 @@
43ecf62
 				 * Once the client does a proper navigate with either setUrl() or setText() then resume as
43ecf62
 				 * normal.  The Mozilla bug for this is https://bugzilla.mozilla.org/show_bug.cgi?id=415789.
43ecf62
 				 */
43ecf62
-				awaitingNavigate = true;
43ecf62
-				rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
43ecf62
-				if (rc != XPCOM.NS_OK) {
43ecf62
-					browser.dispose ();
43ecf62
-					error (rc);
43ecf62
-				}
43ecf62
-				if (result[0] == 0) {
43ecf62
-					browser.dispose ();
43ecf62
-					error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
-				}
43ecf62
-				nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
43ecf62
-			    char[] uri = new char[ABOUT_BLANK.length () + 1];
43ecf62
-			    ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uri, 0);
43ecf62
-				rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
43ecf62
-				webNavigation.Release ();
43ecf62
+//				awaitingNavigate = true;
43ecf62
+//				rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
43ecf62
+//				if (rc != XPCOM.NS_OK) {
43ecf62
+//					browser.dispose ();
43ecf62
+//					error (rc);
43ecf62
+//				}
43ecf62
+//				if (result[0] == 0) {
43ecf62
+//					browser.dispose ();
43ecf62
+//					error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
+//				}
43ecf62
+//				nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
43ecf62
+//			    char[] uri = new char[ABOUT_BLANK.length () + 1];
43ecf62
+//			    ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uri, 0);
43ecf62
+//				rc = webNavigation.LoadURI (uri, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
43ecf62
+//				webNavigation.Release ();
43ecf62
 
43ecf62
 				dialogFactory.isPre_1_9 = false;
43ecf62
 			}
43ecf62
@@ -1264,6 +1265,7 @@
43ecf62
 }
43ecf62
 
43ecf62
 public boolean back () {
43ecf62
+	htmlBytes = null;
43ecf62
 	if (awaitingNavigate) return false;
43ecf62
 
43ecf62
 	int /*long*/[] result = new int /*long*/[1];
43ecf62
@@ -1466,6 +1468,7 @@
43ecf62
 }
43ecf62
 
43ecf62
 public boolean forward () {
43ecf62
+	htmlBytes = null;
43ecf62
 	if (awaitingNavigate) return false;
43ecf62
 
43ecf62
 	int /*long*/[] result = new int /*long*/[1];
43ecf62
@@ -1676,6 +1679,7 @@
43ecf62
 	webBrowser.Release ();
43ecf62
 	webBrowser = null;
43ecf62
 	webBrowserObject = null;
43ecf62
+	htmlBytes = null;
43ecf62
 
43ecf62
 	if (tip != null && !tip.isDisposed ()) tip.dispose ();
43ecf62
 	tip = null;
43ecf62
@@ -1737,6 +1741,7 @@
43ecf62
 }
43ecf62
 
43ecf62
 public void refresh () {
43ecf62
+	htmlBytes = null;
43ecf62
 	if (awaitingNavigate) return;
43ecf62
 
43ecf62
 	int /*long*/[] result = new int /*long*/[1];
43ecf62
@@ -1858,11 +1863,45 @@
43ecf62
 		} else {
43ecf62
 			result[0] = 0;
43ecf62
 			rc = interfaceRequestor.GetInterface (nsIDocShell.NS_IDOCSHELL_IID, result);
43ecf62
-			if (rc != XPCOM.NS_OK) error (rc);
43ecf62
-			if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
-			nsIDocShell docShell = new nsIDocShell (result[0]);
43ecf62
-			rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType,  aContentCharset, 0);
43ecf62
-			docShell.Release ();
43ecf62
+			if (rc == XPCOM.NS_OK) {
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
+				nsIDocShell docShell = new nsIDocShell (result[0]);
43ecf62
+				rc = docShell.LoadStream (inputStream.getAddress (), uri.getAddress (), aContentType,  aContentCharset, 0);
43ecf62
+				docShell.Release ();
43ecf62
+			} else {
43ecf62
+				result[0] = 0;
43ecf62
+				rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result);
43ecf62
+				if (rc == XPCOM.NS_OK) {
43ecf62
+					if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
+					/*
43ecf62
+					* Setting mozilla's content through nsIWebBrowserStream does not cause a page
43ecf62
+					* load to occur, so the events that usually accompany a page change are not
43ecf62
+					* fired.  To make this behave as expected, navigate to about:blank first and
43ecf62
+					* then set the html content once the page has loaded.
43ecf62
+					*/
43ecf62
+					new nsISupports (result[0]).Release ();
43ecf62
+					result[0] = 0;
43ecf62
+
43ecf62
+					/*
43ecf62
+					* If htmlBytes is not null then the about:blank page is already being loaded,
43ecf62
+					* so no Navigate is required.  Just set the html that is to be shown.
43ecf62
+					*/
43ecf62
+					boolean blankLoading = htmlBytes != null;
43ecf62
+					htmlBytes = data;
43ecf62
+					if (blankLoading) return true;
43ecf62
+
43ecf62
+					/* navigate to about:blank */
43ecf62
+					rc = webBrowser.QueryInterface (nsIWebNavigation.NS_IWEBNAVIGATION_IID, result);
43ecf62
+					if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+					if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
+					nsIWebNavigation webNavigation = new nsIWebNavigation (result[0]);
43ecf62
+					result[0] = 0;
43ecf62
+				    char[] uriChars = new char[ABOUT_BLANK.length () + 1];
43ecf62
+				    ABOUT_BLANK.getChars (0, ABOUT_BLANK.length (), uriChars, 0);
43ecf62
+					rc = webNavigation.LoadURI (uriChars, nsIWebNavigation.LOAD_FLAGS_NONE, 0, 0, 0);
43ecf62
+					webNavigation.Release ();
43ecf62
+				}
43ecf62
+			}
43ecf62
 		}
43ecf62
 	}
43ecf62
 	if (rc != XPCOM.NS_OK) error (rc);
43ecf62
@@ -1877,6 +1916,7 @@
43ecf62
 }
43ecf62
 
43ecf62
 public boolean setUrl (String url) {
43ecf62
+	htmlBytes = null;
43ecf62
 	awaitingNavigate = false;
43ecf62
 
43ecf62
 	int /*long*/[] result = new int /*long*/[1];
43ecf62
@@ -1893,6 +1933,7 @@
43ecf62
 }
43ecf62
 
43ecf62
 public void stop () {
43ecf62
+	htmlBytes = null;
43ecf62
 	if (awaitingNavigate) return;
43ecf62
 
43ecf62
 	int /*long*/[] result = new int /*long*/[1];
43ecf62
@@ -2215,6 +2256,108 @@
43ecf62
 			unhookedDOMWindows.remove (ptrObject);
43ecf62
 			new nsISupports (ptrObject.value).Release ();
43ecf62
 		}
43ecf62
+
43ecf62
+		/*
43ecf62
+		* If htmlBytes is not null then there is html from a previous setText() call
43ecf62
+		* waiting to be set into the about:blank page once it has completed loading. 
43ecf62
+		*/
43ecf62
+		if (htmlBytes != null) {
43ecf62
+			nsIRequest req = new nsIRequest (aRequest);
43ecf62
+			int /*long*/ name = XPCOM.nsEmbedCString_new ();
43ecf62
+			rc = req.GetName (name);
43ecf62
+			if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+			int length = XPCOM.nsEmbedCString_Length (name);
43ecf62
+			int /*long*/ buffer = XPCOM.nsEmbedCString_get (name);
43ecf62
+			byte[] dest = new byte[length];
43ecf62
+			XPCOM.memmove (dest, buffer, length);
43ecf62
+			String url = new String (dest);
43ecf62
+			XPCOM.nsEmbedCString_delete (name);
43ecf62
+
43ecf62
+			if (url.startsWith (ABOUT_BLANK)) {
43ecf62
+				/*
43ecf62
+				 * Setting mozilla's content with nsIWebBrowserStream invalidates the 
43ecf62
+				 * DOM listeners that were hooked on it (about:blank), so remove them and
43ecf62
+				 * add new ones after the content has been set.
43ecf62
+				 */
43ecf62
+				unhookDOMListeners ();
43ecf62
+
43ecf62
+				rc = XPCOM.NS_GetServiceManager (result);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
43ecf62
+
43ecf62
+				nsIServiceManager serviceManager = new nsIServiceManager (result[0]);
43ecf62
+				result[0] = 0;
43ecf62
+				rc = serviceManager.GetService (XPCOM.NS_IOSERVICE_CID, nsIIOService.NS_IIOSERVICE_IID, result);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
43ecf62
+				serviceManager.Release ();
43ecf62
+
43ecf62
+				nsIIOService ioService = new nsIIOService (result[0]);
43ecf62
+				result[0] = 0;
43ecf62
+				/*
43ecf62
+				* Note.  Mozilla ignores LINK tags used to load CSS stylesheets
43ecf62
+				* when the URI protocol for the nsInputStreamChannel
43ecf62
+				* is about:blank.  The fix is to specify the file protocol.
43ecf62
+				*/
43ecf62
+				byte[] aString = MozillaDelegate.wcsToMbcs (null, URI_FROMMEMORY, false);
43ecf62
+				int /*long*/ aSpec = XPCOM.nsEmbedCString_new (aString, aString.length);
43ecf62
+				rc = ioService.NewURI (aSpec, null, 0, result);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
43ecf62
+				XPCOM.nsEmbedCString_delete (aSpec);
43ecf62
+				ioService.Release ();
43ecf62
+
43ecf62
+				nsIURI uri = new nsIURI (result[0]);
43ecf62
+				result[0] = 0;
43ecf62
+
43ecf62
+				rc = webBrowser.QueryInterface (nsIWebBrowserStream.NS_IWEBBROWSERSTREAM_IID, result);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_NOINTERFACE);
43ecf62
+
43ecf62
+				nsIWebBrowserStream stream = new nsIWebBrowserStream (result[0]);
43ecf62
+				result[0] = 0;
43ecf62
+
43ecf62
+				byte[] contentTypeBuffer = MozillaDelegate.wcsToMbcs (null, "text/html", true); // $NON-NLS-1$
43ecf62
+				int /*long*/ aContentType = XPCOM.nsEmbedCString_new (contentTypeBuffer, contentTypeBuffer.length);
43ecf62
+
43ecf62
+				rc = stream.OpenStream (uri.getAddress (), aContentType);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				int /*long*/ ptr = C.malloc (htmlBytes.length);
43ecf62
+				XPCOM.memmove (ptr, htmlBytes, htmlBytes.length);
43ecf62
+				int pageSize = 8192;
43ecf62
+				int pageCount = htmlBytes.length / pageSize + 1;
43ecf62
+				int /*long*/ current = ptr;
43ecf62
+				for (int i = 0; i < pageCount; i++) {
43ecf62
+					length = i == pageCount - 1 ? htmlBytes.length % pageSize : pageSize;
43ecf62
+					if (length > 0) {
43ecf62
+						rc = stream.AppendToStream (current, length);
43ecf62
+						if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+					}
43ecf62
+					current += pageSize;
43ecf62
+				}
43ecf62
+				rc = stream.CloseStream ();
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				C.free (ptr);
43ecf62
+				XPCOM.nsEmbedCString_delete (aContentType);
43ecf62
+				stream.Release ();
43ecf62
+				uri.Release ();
43ecf62
+				htmlBytes = null;
43ecf62
+
43ecf62
+				rc = webBrowser.GetContentDOMWindow (result);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
+				boolean isTop = result[0] == domWindow.getAddress ();
43ecf62
+				new nsISupports (result[0]).Release ();
43ecf62
+				result[0] = 0;
43ecf62
+				rc = domWindow.QueryInterface (nsIDOMEventTarget.NS_IDOMEVENTTARGET_IID, result);
43ecf62
+				if (rc != XPCOM.NS_OK) error (rc);
43ecf62
+				if (result[0] == 0) error (XPCOM.NS_ERROR_NO_INTERFACE);
43ecf62
+				nsIDOMEventTarget target = new nsIDOMEventTarget (result[0]);
43ecf62
+				result[0] = 0;
43ecf62
+				hookDOMListeners (target, isTop);
43ecf62
+				target.Release ();
43ecf62
+			}
43ecf62
+		}
43ecf62
 		domWindow.Release ();
43ecf62
 
43ecf62
 		/*
43ecf62
Index: Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java
43ecf62
===================================================================
43ecf62
RCS file: Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java
43ecf62
diff -N Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java
43ecf62
--- /dev/null	1 Jan 1970 00:00:00 -0000
43ecf62
+++ Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/nsIWebBrowserStream.java	1 Jan 1970 00:00:00 -0000
43ecf62
@@ -0,0 +1,55 @@
43ecf62
+/* ***** BEGIN LICENSE BLOCK *****
43ecf62
+ * Version: MPL 1.1
43ecf62
+ *
43ecf62
+ * The contents of this file are subject to the Mozilla Public License Version
43ecf62
+ * 1.1 (the "License"); you may not use this file except in compliance with
43ecf62
+ * the License. You may obtain a copy of the License at
43ecf62
+ * http://www.mozilla.org/MPL/
43ecf62
+ *
43ecf62
+ * Software distributed under the License is distributed on an "AS IS" basis,
43ecf62
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
43ecf62
+ * for the specific language governing rights and limitations under the
43ecf62
+ * License.
43ecf62
+ *
43ecf62
+ * The Original Code is Mozilla Communicator client code, released March 31, 1998.
43ecf62
+ *
43ecf62
+ * The Initial Developer of the Original Code is
43ecf62
+ * Netscape Communications Corporation.
43ecf62
+ * Portions created by Netscape are Copyright (C) 1998-1999
43ecf62
+ * Netscape Communications Corporation.  All Rights Reserved.
43ecf62
+ *
43ecf62
+ * Contributor(s):
43ecf62
+ *
43ecf62
+ * IBM
43ecf62
+ * -  Binding to permit interfacing between Mozilla and SWT
43ecf62
+ * -  Copyright (C) 2003, 2009 IBM Corp.  All Rights Reserved.
43ecf62
+ *
43ecf62
+ * ***** END LICENSE BLOCK ***** */
43ecf62
+package org.eclipse.swt.internal.mozilla;
43ecf62
+
43ecf62
+public class nsIWebBrowserStream extends nsISupports {
43ecf62
+
43ecf62
+	static final int LAST_METHOD_ID = nsISupports.LAST_METHOD_ID + 3;
43ecf62
+
43ecf62
+	public static final String NS_IWEBBROWSERSTREAM_IID_STR =
43ecf62
+		"86d02f0e-219b-4cfc-9c88-bd98d2cce0b8";
43ecf62
+
43ecf62
+	public static final nsID NS_IWEBBROWSERSTREAM_IID =
43ecf62
+		new nsID(NS_IWEBBROWSERSTREAM_IID_STR);
43ecf62
+
43ecf62
+	public nsIWebBrowserStream(int /*long*/ address) {
43ecf62
+		super(address);
43ecf62
+	}
43ecf62
+
43ecf62
+	public int OpenStream(int /*long*/ aBaseURI, int /*long*/ aContentType) {
43ecf62
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 1, getAddress(), aBaseURI, aContentType);
43ecf62
+	}
43ecf62
+
43ecf62
+	public int AppendToStream(int /*long*/ aData, int aLen) {
43ecf62
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 2, getAddress(), aData, aLen);
43ecf62
+	}
43ecf62
+
43ecf62
+	public int CloseStream() {
43ecf62
+		return XPCOM.VtblCall(nsISupports.LAST_METHOD_ID + 3, getAddress());
43ecf62
+	}
43ecf62
+}