Fix bug on IE where onload events don't fire for IFrames.
This is a bugfix for
http://code.google.com/p/google-web-toolkit/issues/detail?id=1720
Review at http://gwt-code-reviews.appspot.com/1294801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9851 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java b/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java
index 7bed0d0..36b1b26 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java
@@ -31,6 +31,9 @@
private static JavaScriptObject callDispatchDblClickEvent;
@SuppressWarnings("unused")
+ private static JavaScriptObject callDispatchOnLoadEvent;
+
+ @SuppressWarnings("unused")
private static JavaScriptObject callDispatchUnhandledEvent;
/**
@@ -168,15 +171,18 @@
$wnd['__gwt_dispatchEvent_' + moduleName] = dispatchEvent;
@com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent = new Function('w',
'return function() { w.__gwt_dispatchEvent_' + moduleName + '.call(this) }')($wnd);
-
+
$wnd['__gwt_dispatchDblClickEvent_' + moduleName] = dispatchDblClickEvent;
@com.google.gwt.user.client.impl.DOMImplTrident::callDispatchDblClickEvent = new Function('w',
'return function() { w.__gwt_dispatchDblClickEvent_' + moduleName + '.call(this)}')($wnd);
-
+
$wnd['__gwt_dispatchUnhandledEvent_' + moduleName] = dispatchUnhandledEvent;
@com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent = new Function('w',
'return function() { w.__gwt_dispatchUnhandledEvent_' + moduleName + '.call(this)}')($wnd);
+ @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent = new Function('w',
+ 'return function() { w.__gwt_dispatchUnhandledEvent_' + moduleName + '.call(w.event.srcElement)}')($wnd);
+
// We need to create these delegate functions to fix up the 'this' context.
// Normally, 'this' is the firing element, but this is only true for
// 'onclick = ...' event handlers, not for handlers setup via attachEvent().
@@ -268,8 +274,18 @@
@com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
if (chMask & 0x04000) elem.onscroll = (bits & 0x04000) ?
@com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
- if (chMask & 0x08000) elem.onload = (bits & 0x08000) ?
- @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent : null;
+ if (chMask & 0x08000) {
+ if (elem.nodeName == "IFRAME") {
+ if (bits & 0x08000) {
+ elem.attachEvent('onload', @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent);
+ } else {
+ elem.detachEvent('onload', @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent);
+ }
+ } else {
+ elem.onload = (bits & 0x08000) ?
+ @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchUnhandledEvent : null;
+ }
+ }
if (chMask & 0x10000) elem.onerror = (bits & 0x10000) ?
@com.google.gwt.user.client.impl.DOMImplTrident::callDispatchEvent : null;
if (chMask & 0x20000) elem.onmousewheel = (bits & 0x20000) ?
diff --git a/user/src/com/google/gwt/user/client/ui/Frame.java b/user/src/com/google/gwt/user/client/ui/Frame.java
index c6b09da..cdd8b48 100644
--- a/user/src/com/google/gwt/user/client/ui/Frame.java
+++ b/user/src/com/google/gwt/user/client/ui/Frame.java
@@ -19,6 +19,10 @@
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.FrameElement;
import com.google.gwt.dom.client.IFrameElement;
+import com.google.gwt.event.dom.client.HasLoadHandlers;
+import com.google.gwt.event.dom.client.LoadEvent;
+import com.google.gwt.event.dom.client.LoadHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
/**
* A widget that wraps an IFRAME element, which can contain an arbitrary web
@@ -37,7 +41,7 @@
* <h3>Example</h3> {@example com.google.gwt.examples.FrameExample}
* </p>
*/
-public class Frame extends Widget {
+public class Frame extends Widget implements HasLoadHandlers {
static final String DEFAULT_STYLENAME = "gwt-Frame";
@@ -93,6 +97,17 @@
}
/**
+ * Adds a {@link LoadEvent} load handler which will be called when the frame
+ * loads.
+ *
+ * @param handler the load handler
+ * @return {@link HandlerRegistration} that can be used to remove this handler
+ */
+ public HandlerRegistration addLoadHandler(LoadHandler handler) {
+ return addDomHandler(handler, LoadEvent.getType());
+ }
+
+ /**
* Gets the URL of the frame's resource.
*
* @return the frame's URL
diff --git a/user/test/com/google/gwt/dom/DOMSuite.java b/user/test/com/google/gwt/dom/DOMSuite.java
index 42d0be6..231c3d8 100644
--- a/user/test/com/google/gwt/dom/DOMSuite.java
+++ b/user/test/com/google/gwt/dom/DOMSuite.java
@@ -18,6 +18,7 @@
import com.google.gwt.dom.client.DocumentTest;
import com.google.gwt.dom.client.ElementTest;
import com.google.gwt.dom.client.FormTests;
+import com.google.gwt.dom.client.FrameTests;
import com.google.gwt.dom.client.MapTests;
import com.google.gwt.dom.client.NodeTest;
import com.google.gwt.dom.client.SelectTests;
@@ -40,6 +41,7 @@
suite.addTestSuite(NodeTest.class);
suite.addTestSuite(ElementTest.class);
suite.addTestSuite(FormTests.class);
+ suite.addTestSuite(FrameTests.class);
suite.addTestSuite(MapTests.class);
suite.addTestSuite(SelectTests.class);
suite.addTestSuite(StyleInjectorTest.class);
diff --git a/user/test/com/google/gwt/dom/client/FrameTests.java b/user/test/com/google/gwt/dom/client/FrameTests.java
index 183ea9d..cb6226a 100644
--- a/user/test/com/google/gwt/dom/client/FrameTests.java
+++ b/user/test/com/google/gwt/dom/client/FrameTests.java
@@ -16,12 +16,20 @@
package com.google.gwt.dom.client;
import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Frame;
+import com.google.gwt.user.client.ui.RootPanel;
+
+import com.google.gwt.event.dom.client.LoadEvent;
+import com.google.gwt.event.dom.client.LoadHandler;
/**
* Tests for the FrameElement and IFrameElement classes.
*/
public class FrameTests extends GWTTestCase {
+ private static final int FRAME_LOAD_DELAY = 3000;
+
@Override
public String getModuleName() {
return "com.google.gwt.dom.DOMTest";
@@ -34,4 +42,52 @@
doc.getBody().appendChild(iframe);
assertNotNull(iframe.getContentDocument());
}
+
+ public void testOnLoadEventFiresWithBrowerEvent() {
+ delayTestFinish(FRAME_LOAD_DELAY);
+
+ Frame frame = new Frame() {
+ public void onBrowserEvent(Event event) {
+ if (event.getTypeInt() == Event.ONLOAD) {
+ finishTest();
+ }
+ super.onBrowserEvent(event);
+ }
+ };
+
+ frame.sinkEvents(Event.ONLOAD);
+ RootPanel.get().add(frame);
+ frame.setUrl("iframetest.html");
+ }
+
+ public void testOnLoadEventFiresWithLoadHandler() {
+ delayTestFinish(FRAME_LOAD_DELAY);
+
+ Frame frame = new Frame();
+ frame.addLoadHandler(new LoadHandler() {
+ public void onLoad(LoadEvent event) {
+ finishTest();
+ }
+ });
+
+ RootPanel.get().add(frame);
+ frame.setUrl("iframetest.html");
+ }
+
+ public void testOnLoadEventFiresWithDomLoadHandler() {
+ delayTestFinish(FRAME_LOAD_DELAY);
+
+ Frame frame = new Frame() {
+ {
+ addDomHandler(new LoadHandler() {
+ public void onLoad(LoadEvent event) {
+ finishTest();
+ }
+ }, LoadEvent.getType());
+ }
+ };
+
+ RootPanel.get().add(frame);
+ frame.setUrl("iframetest.html");
+ }
}
diff --git a/user/test/com/google/gwt/dom/public-test/iframetest.html b/user/test/com/google/gwt/dom/public-test/iframetest.html
new file mode 100644
index 0000000..0ebc59c
--- /dev/null
+++ b/user/test/com/google/gwt/dom/public-test/iframetest.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <title>
+ IFRAME TEST
+ </title>
+ </head>
+ <body>
+ IFRAME TEST
+ </body>
+</html>