M webclient/classes_spec/org/mozilla/webclient/NewWindowEvent.java
- changes for new responsibilities of NewWindowEvent
* <p>Indicates the browser is requesting a new window be created to
* display a new <code>BrowserControlCanvas</code> 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.</p>
M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeBrowserControlCanvas.java
M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaBrowserControlCanvas.java
M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/Win32BrowserControlCanvas.java
- introduce new performPlatformAppropriateNewWindowRealization
* Allow platform specific handling of new window creation.
M webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java
- modify the contract for new window creation
M webclient/test/automated/src/classes/org/mozilla/webclient/WindowCreatorTest.java
- verify it all works.
git-svn-id: svn://10.0.0.236/trunk@228930 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -22,7 +22,96 @@
|
||||
|
||||
package org.mozilla.webclient;
|
||||
|
||||
import java.awt.Container;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* <p>Indicates the browser is requesting a new window be created to
|
||||
* display a new <code>BrowserControlCanvas</code> 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.</p>
|
||||
*
|
||||
* <p>Usage contract:</p>
|
||||
*
|
||||
* <p>The unfortunately complex usage contract to accomodate differences
|
||||
* in the UI threading models in a platform indepent manner.</p>
|
||||
*
|
||||
* <p>On the application main thread, do something like this:</p>
|
||||
*
|
||||
* <code><pre>
|
||||
|
||||
final List<Runnable> realizeNewWindowRunnableList =
|
||||
new CopyOnWriteArrayList<Runnable>();
|
||||
|
||||
<a href="EventRegistrationImpl.html">eventRegistration</a>.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();
|
||||
}
|
||||
* </pre></code>
|
||||
*
|
||||
* <p>The above code accomplishes the folliwng goals:</p>
|
||||
|
||||
* <p>Create a thread safe list data structure. This will hold the
|
||||
* <code>Runnable</code> that we define to create the parent window and
|
||||
* make it visible. Add a <code><a
|
||||
* href="NewWindowListener.html">NewWindowListener</a></code> instance
|
||||
* to the "main" <code>BrowserControl</code>. When this listener
|
||||
* instance receives an <code>eventDispatched</code> call (on a platform
|
||||
* specific <code>Thread</code>), it must create a <b>new</b>
|
||||
* <code>BrowserControl</code>, gets its
|
||||
* <code>BrowserControlCanvas</code>, 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
|
||||
* <code>Thread</code>. The <code>toString()</code> implementation is
|
||||
* just good practice for debugging.</p>
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
*/
|
||||
|
||||
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<Runnable> browserWillAdd;
|
||||
|
||||
public void setRealizeNewWindowRunnableList(List<Runnable> browserWillAdd){
|
||||
this.browserWillAdd = browserWillAdd;
|
||||
}
|
||||
|
||||
public List<Runnable> 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
|
||||
|
||||
@@ -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<Runnable> addToList =
|
||||
event.getRealizeNewWindowRunnableList();
|
||||
event.getRealizeNewWindowRunnable().run();
|
||||
addToList.add(new Runnable() { public void run() {} });
|
||||
}
|
||||
|
||||
public static NativeEventThread newNativeEventThread(WrapperFactory owner) {
|
||||
NativeEventThread result = new CocoaAppKitThreadDelegatingNativeEventThread("WebclientEventThread",
|
||||
|
||||
@@ -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
|
||||
@@ -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());
|
||||
|
||||
@@ -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<Runnable> 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",
|
||||
|
||||
Reference in New Issue
Block a user