diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/NewWindowEvent.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/NewWindowEvent.java
index 6148d9ab031..d290eb2e6e1 100644
--- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/NewWindowEvent.java
+++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/NewWindowEvent.java
@@ -22,7 +22,96 @@
package org.mozilla.webclient;
-import java.awt.Container;
+import java.util.List;
+
+/**
+ *
+ *
Indicates the browser is requesting a new window be created to
+ * display a new BrowserControlCanvas instance. This
+ * mechanism is only necessary if your embedding application wishes to
+ * allow the browser to pop up new windows (or tabs). Such is often the
+ * case when the user clicks on an href with a "target" attribute, or
+ * the embedding application wants to enable some right-click "open in
+ * new window" or "open in new tab" feature.
+ *
+ * Usage contract:
+ *
+ * The unfortunately complex usage contract to accomodate differences
+ * in the UI threading models in a platform indepent manner.
+ *
+ * On the application main thread, do something like this:
+ *
+ *
+
+final List realizeNewWindowRunnableList =
+ new CopyOnWriteArrayList();
+
+eventRegistration.setNewWindowListener(new NewWindowListener() {
+ public void eventDispatched(WebclientEvent wcEvent) {
+ NewWindowEvent event = (NewWindowEvent) wcEvent;
+ final BrowserControlCanvas secondCanvas;
+
+ try {
+ secondBrowserControl =
+ BrowserControlFactory.newBrowserControl();
+ secondCanvas = (BrowserControlCanvas)
+ secondBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
+ } catch (Throwable e) {
+ System.out.println(e.getMessage());
+ fail();
+ return;
+ }
+ event.setBrowserControl(secondBrowserControl);
+ event.setRealizeNewWindowRunnableList(realizeNewWindowRunnableList);
+ event.setRealizeNewWindowRunnable(new Runnable() {
+ public void run() {
+ secondFrame.add(secondCanvas, BorderLayout.CENTER);
+ secondFrame.setVisible(true);
+ secondCanvas.setVisible(true);
+ }
+ public String toString() {
+ return "WindowCreatorTest newWindowRunnable";
+ }
+ });
+ }
+ });
+
+// ... continue with browser code.
+
+ while (realizeNewWindowRunnableList.isEmpty()) {
+ Thread.currentThread().sleep(1000);
+ }
+
+ for (Runnable cur : realizeNewWindowRunnableList) {
+ cur.run();
+ }
+ *
+ *
+ * The above code accomplishes the folliwng goals:
+
+ * Create a thread safe list data structure. This will hold the
+ * Runnable that we define to create the parent window and
+ * make it visible. Add a NewWindowListener instance
+ * to the "main" BrowserControl. When this listener
+ * instance receives an eventDispatched call (on a platform
+ * specific Thread), it must create a new
+ * BrowserControl, gets its
+ * BrowserControlCanvas, store the canvas into the event,
+ * store the thread safe list data structure into the event, and store a
+ * Runnable into the event that adds the canvas to its parent container,
+ * and sets the parent container and the canvas visible. This Runnable
+ * will be called at a platform specific time, on a platform specific
+ * Thread. The toString() implementation is
+ * just good practice for debugging.
+ *
+ * Meanwhile, back on the main thread the thread safe list data
+ * structure mest be polled, as often as desired, until Runnable appears
+ * in the list. It will have been placed there by the Webclient API and
+ * the embedding application is required to run() it on the main
+ * thread.
+ *
+ */
public class NewWindowEvent extends WebclientEvent
{
@@ -46,15 +135,37 @@ public void setBrowserControl(BrowserControl newBrowserControl) {
browserControl = newBrowserControl;
}
-private Container parentContainer;
+private Runnable realizeNewWindowRunnable;
- public Container getParentContainer() {
- return parentContainer;
+protected List browserWillAdd;
+
+public void setRealizeNewWindowRunnableList(List browserWillAdd){
+ this.browserWillAdd = browserWillAdd;
+}
+
+public List getRealizeNewWindowRunnableList() {
+ return browserWillAdd;
+}
+
+public static class RealizeNewWindowEvent {
+ private BrowserControl browserControl;
+
+ public BrowserControl getBrowserControl() {
+ return browserControl;
+ }
+
+ public void setBrowserControl(BrowserControl browserControl) {
+ this.browserControl = browserControl;
+ }
+}
+
+ public Runnable getRealizeNewWindowRunnable() {
+ return realizeNewWindowRunnable;
}
- public void setParentContainer(Container parentContainer) {
- this.parentContainer = parentContainer;
+ public void setRealizeNewWindowRunnable(Runnable realizeNewWindowRunnable) {
+ this.realizeNewWindowRunnable = realizeNewWindowRunnable;
}
-
+
} // end of class NewWindowEvent
diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java
index 1abfab645fb..7c3bf491ee0 100644
--- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java
+++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java
@@ -26,12 +26,12 @@
package org.mozilla.webclient.impl.wrapper_native;
-import org.mozilla.webclient.BrowserControlCanvas;
-import java.awt.*;
+import java.util.List;
import java.util.logging.Logger;
import org.mozilla.util.Log;
import org.mozilla.util.ReturnRunnable;
+import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.impl.WrapperFactory;
/**
@@ -80,6 +80,13 @@ public class CocoaBrowserControlCanvas extends NativeBrowserControlCanvas {
return nativeView;
}
+
+ void performPlatformAppropriateNewWindowRealization(NewWindowEvent event) {
+ List addToList =
+ event.getRealizeNewWindowRunnableList();
+ event.getRealizeNewWindowRunnable().run();
+ addToList.add(new Runnable() { public void run() {} });
+ }
public static NativeEventThread newNativeEventThread(WrapperFactory owner) {
NativeEventThread result = new CocoaAppKitThreadDelegatingNativeEventThread("WebclientEventThread",
diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java
index 1422f1acb75..2eb367ae1f3 100644
--- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java
+++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java
@@ -21,8 +21,6 @@
*/
package org.mozilla.webclient.impl.wrapper_native;
-import java.awt.BorderLayout;
-import java.awt.Container;
import org.mozilla.util.ParameterCheck;
import java.util.ArrayList;
@@ -47,13 +45,14 @@ import org.mozilla.util.Log;
import org.mozilla.util.ReturnRunnable;
import org.mozilla.webclient.BrowserControl;
+import org.mozilla.webclient.BrowserControlCanvas;
import org.mozilla.webclient.EventRegistration2;
-import org.mozilla.webclient.impl.BrowserControlImpl;
import org.mozilla.webclient.impl.WrapperFactory;
import org.mozilla.webclient.DocumentLoadEvent;
import org.mozilla.webclient.DocumentLoadListener;
import org.mozilla.webclient.PageInfoListener;
import org.mozilla.webclient.NewWindowEvent;
+import org.mozilla.webclient.NewWindowEvent.RealizeNewWindowEvent;
import org.mozilla.webclient.NewWindowListener;
import org.mozilla.webclient.WCKeyEvent;
import org.mozilla.webclient.WebclientEvent;
@@ -551,28 +550,18 @@ private EventObject createKeyEvent(long eventType, Object eventData) {
return keyEvent;
}
-private int getNativeBrowserControlFromNewWindowEvent(NewWindowEvent event) {
- NativeBrowserControlCanvas
- currentCanvas = null,
- newCanvas = null;
- BrowserControlImpl newBrowserControl = null;
+private int getNativeBrowserControlFromNewWindowEvent(final NewWindowEvent event) {
+ final BrowserControl newBrowserControl;
+ NativeBrowserControlCanvas newCanvas = null;
EventRegistration2 newEventRegistration = null;
- Container parentContainer = null;
int result = 0;
- if (null == (newBrowserControl =
- (BrowserControlImpl) event.getBrowserControl())) {
+ if (null == (newBrowserControl = event.getBrowserControl())) {
return 0;
}
- if (null == (parentContainer =
- event.getParentContainer())) {
- return 0;
- }
- currentCanvas = browserControlCanvas;
try {
- newCanvas =
- (NativeBrowserControlCanvas)
+ newCanvas = (NativeBrowserControlCanvas)
newBrowserControl.queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
} catch (ClassNotFoundException cnfe) {
if (LOGGER.isLoggable(Level.SEVERE)) {
@@ -582,10 +571,6 @@ private int getNativeBrowserControlFromNewWindowEvent(NewWindowEvent event) {
throw new IllegalStateException(cnfe);
}
- parentContainer.add(newCanvas, BorderLayout.CENTER);
- parentContainer.setVisible(true);
- newCanvas.setVisible(true);
-
try {
newEventRegistration = (EventRegistration2)
newBrowserControl.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
@@ -602,6 +587,8 @@ private int getNativeBrowserControlFromNewWindowEvent(NewWindowEvent event) {
return 0;
}
+ newCanvas.performPlatformAppropriateNewWindowRealization(event);
+
result = ((ImplObjectNative)newEventRegistration).getNativeBrowserControl();
return result;
@@ -834,4 +821,4 @@ class URIToStringMap extends Object implements Map {
}
-} // end of class EventRegistrationImpl
+} // end of class EventRegistrationImpl
\ No newline at end of file
diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeBrowserControlCanvas.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeBrowserControlCanvas.java
index b977f6e046e..80a2970f3b5 100644
--- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeBrowserControlCanvas.java
+++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeBrowserControlCanvas.java
@@ -32,6 +32,7 @@ import org.mozilla.util.Assert;
import org.mozilla.util.Log;
import org.mozilla.webclient.BrowserControl;
import org.mozilla.webclient.BrowserControlCanvas;
+import org.mozilla.webclient.NewWindowEvent;
import org.mozilla.webclient.WindowControl;
import org.mozilla.webclient.impl.BrowserControlImpl;
import org.mozilla.webclient.impl.WrapperFactory;
@@ -88,6 +89,13 @@ abstract class NativeBrowserControlCanvas extends BrowserControlCanvas {
abstract protected int getWindow();
+ /**
+ * Allow platform specific handling of new window creation.
+ *
+ */
+
+ abstract void performPlatformAppropriateNewWindowRealization(NewWindowEvent event);
+
private void createNativeBrowser() throws IllegalStateException {
try {
Rectangle r = new Rectangle(getBoundsRelativeToWindow());
diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/Win32BrowserControlCanvas.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/Win32BrowserControlCanvas.java
index 07807bc7807..b4c11316b15 100644
--- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/Win32BrowserControlCanvas.java
+++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/Win32BrowserControlCanvas.java
@@ -22,7 +22,9 @@
package org.mozilla.webclient.impl.wrapper_native;
+import java.util.List;
import org.mozilla.util.ReturnRunnable;
+import org.mozilla.webclient.NewWindowEvent;
/**
@@ -33,7 +35,7 @@ import org.mozilla.util.ReturnRunnable;
* There is one instance of the BrowserControlCanvas per top level awt Frame.
- * @version $Id: Win32BrowserControlCanvas.java,v 1.5 2007-06-19 20:18:11 edburns%acm.org Exp $
+ * @version $Id: Win32BrowserControlCanvas.java,v 1.6 2007-06-28 12:05:07 edburns%acm.org Exp $
*
* @see org.mozilla.webclient.BrowserControlCanvasFactory
*
@@ -76,6 +78,23 @@ public class Win32BrowserControlCanvas extends NativeBrowserControlCanvas {
});
return result.intValue();
}
+
+ void performPlatformAppropriateNewWindowRealization(final NewWindowEvent event) {
+ final List addToList =
+ event.getRealizeNewWindowRunnableList();
+ NativeEventThread.instance.pushRunnable(new Runnable() {
+ public void run() {
+ addToList.add(event.getRealizeNewWindowRunnable());
+ }
+
+ public String toString() {
+ return "EventRegistrationImpl.RealizeNewWindowEvent";
+ }
+ });
+
+ NativeEventThread.instance.runUntilEventOfType(WindowControlImpl.NativeRealizeWCRunnable.class);
+ }
+
public static NativeEventThread newNativeEventThread(WrapperFactory owner) {
NativeEventThread result = new NativeEventThread("WebclientEventThread",
diff --git a/mozilla/java/webclient/test/automated/src/classes/org/mozilla/webclient/WindowCreatorTest.java b/mozilla/java/webclient/test/automated/src/classes/org/mozilla/webclient/WindowCreatorTest.java
index 603c2276296..1fc97fd4299 100644
--- a/mozilla/java/webclient/test/automated/src/classes/org/mozilla/webclient/WindowCreatorTest.java
+++ b/mozilla/java/webclient/test/automated/src/classes/org/mozilla/webclient/WindowCreatorTest.java
@@ -1,5 +1,5 @@
/*
- * $Id: WindowCreatorTest.java,v 1.6 2007-06-19 20:18:13 edburns%acm.org Exp $
+ * $Id: WindowCreatorTest.java,v 1.7 2007-06-28 12:05:07 edburns%acm.org Exp $
*/
/*
@@ -34,8 +34,10 @@ import java.awt.Frame;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.BorderLayout;
-import java.awt.Container;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import org.mozilla.mcp.junit.WebclientTestCase;
+import org.mozilla.webclient.NewWindowEvent.RealizeNewWindowEvent;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -62,6 +64,10 @@ public class WindowCreatorTest extends WebclientTestCase {
static EventRegistration2 eventRegistration;
static boolean keepWaiting;
+
+ static BrowserControl secondBrowserControl;
+ static Frame secondFrame = null;
+
//
// Constants
@@ -73,6 +79,9 @@ public class WindowCreatorTest extends WebclientTestCase {
public void testNewWindow() throws Exception {
BrowserControl firstBrowserControl = null;
+ secondFrame = new Frame();
+ secondFrame.setBounds(100, 100, 540, 380);
+
final DocumentLoadListenerImpl listener =
new DocumentLoadListenerImpl() {
public void doEndCheck() {
@@ -105,46 +114,39 @@ public class WindowCreatorTest extends WebclientTestCase {
eventRegistration.addDocumentLoadListener(listener);
final BitSet bitSet = new BitSet();
- final WebclientWrapper secondBrowser = new WebclientWrapper();
+ final List realizeNewWindowRunnableList =
+ new CopyOnWriteArrayList();
eventRegistration.setNewWindowListener(new NewWindowListener() {
public void eventDispatched(WebclientEvent wcEvent) {
bitSet.set(0);
NewWindowEvent event = (NewWindowEvent) wcEvent;
- BrowserControl secondBrowserControl = null;
- EventRegistration2 secondEventRegistration = null;
- Frame parentContainer = new Frame();
- parentContainer.setBounds(100, 100, 540, 380);
+ final BrowserControlCanvas secondCanvas;
try {
secondBrowserControl =
BrowserControlFactory.newBrowserControl();
- secondEventRegistration =
- (EventRegistration2)
- secondBrowserControl.queryInterface(BrowserControl.EVENT_REGISTRATION_NAME);
-
- assertNotNull(secondEventRegistration);
-
+ secondCanvas = (BrowserControlCanvas)
+ secondBrowserControl.
+ queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
} catch (Throwable e) {
System.out.println(e.getMessage());
fail();
+ return;
}
- secondEventRegistration.addDocumentLoadListener(new DocumentLoadListenerImpl() {
- public void doEndCheck() {
- secondBrowser.setKeepWaiting(false);
+ event.setBrowserControl(secondBrowserControl);
+ event.setRealizeNewWindowRunnableList(realizeNewWindowRunnableList);
+ event.setRealizeNewWindowRunnable(new Runnable() {
+ public void run() {
+ secondFrame.add(secondCanvas, BorderLayout.CENTER);
+ secondFrame.setVisible(true);
+ secondCanvas.setVisible(true);
+ }
+ public String toString() {
+ return "WindowCreatorTest newWindowRunnable";
}
});
- event.setBrowserControl(secondBrowserControl);
- event.setParentContainer(parentContainer);
- // Pass the content of the new window back to the
- // main Thread.
- secondBrowser.setParentContainer(parentContainer);
- secondBrowser.setBrowserControl(secondBrowserControl);
- secondBrowser.setEventRegistration(secondEventRegistration);
- secondBrowser.setKeepWaiting(false);
-
-
}
});
@@ -160,8 +162,6 @@ public class WindowCreatorTest extends WebclientTestCase {
Thread.currentThread().sleep(1000);
}
- secondBrowser.setKeepWaiting(true);
-
Robot robot = new Robot();
Document dom = currentPage.getDOM();
@@ -190,68 +190,32 @@ public class WindowCreatorTest extends WebclientTestCase {
robot.mouseRelease(InputEvent.BUTTON1_MASK);
- // keep waiting until the second window is ready to make visible
- while (secondBrowser.isKeepWaiting()) {
- Thread.currentThread().sleep(1000);
- }
-
- BrowserControlCanvas secondCanvas = (BrowserControlCanvas)
- secondBrowser.getBrowserControl().queryInterface(BrowserControl.BROWSER_CONTROL_CANVAS_NAME);
- CurrentPage2 secondCurrentPage = (CurrentPage2)
- secondBrowser.getBrowserControl().queryInterface(BrowserControl.CURRENT_PAGE_NAME);
-
+ while (realizeNewWindowRunnableList.isEmpty()) {
+ Thread.currentThread().sleep(1000);
+ }
+
assertTrue(!bitSet.isEmpty());
- assertNotNull(secondCurrentPage);
- secondCurrentPage.selectAll();
- selection = secondCurrentPage.getSelection();
- assertTrue(-1 !=selection.toString().indexOf("This is page 1 of the WindowCreatorTest."));
-
- secondBrowser.getParentContainer().setVisible(false);
- BrowserControlFactory.deleteBrowserControl(secondBrowser.getBrowserControl());
+ for (Runnable cur : realizeNewWindowRunnableList) {
+ cur.run();
+ Thread.currentThread().sleep(5000);
+ CurrentPage2 secondCurrentPage = (CurrentPage2)
+ secondBrowserControl.queryInterface(BrowserControl.CURRENT_PAGE_NAME);
+ assertNotNull(secondCurrentPage);
+
+ secondCurrentPage.selectAll();
+ selection = secondCurrentPage.getSelection();
+ assertTrue(-1 !=selection.toString().indexOf("This is page 1 of the WindowCreatorTest."));
+
+ secondFrame.setVisible(false);
+ BrowserControlFactory.deleteBrowserControl(secondBrowserControl);
+ }
+
frame.setVisible(false);
BrowserControlFactory.deleteBrowserControl(firstBrowserControl);
}
-}
-
-class WebclientWrapper {
- private boolean keepWaiting = true;
- private BrowserControl browserControl = null;
- private BrowserControlCanvas canvas = null;
- private EventRegistration2 eventRegistration = null;
- private Container parentContainer;
-
- public BrowserControl getBrowserControl() {
- return browserControl;
- }
-
- public void setBrowserControl(BrowserControl browserControl) {
- this.browserControl = browserControl;
- }
-
- public void setEventRegistration(EventRegistration2 eventRegistration) {
- this.eventRegistration = eventRegistration;
- }
-
- public boolean isKeepWaiting() {
- return keepWaiting;
- }
-
- public void setKeepWaiting(boolean keepWaiting) {
- this.keepWaiting = keepWaiting;
- }
-
- public Container getParentContainer() {
- return parentContainer;
- }
-
- public void setParentContainer(Container parentContainer) {
- this.parentContainer = parentContainer;
- }
-
-}
-
+}
\ No newline at end of file