Fix bug for IE frames where onload events don't fire. Issue: http://code.google.com/p/google-webtoolkit/issues/detail?id=1720 Review at http://gwt-code-reviews.appspot.com/1353801 Review by: jlabanca@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9785 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java b/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java index 5b02b1c..abc2162 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplOpera.java
@@ -59,7 +59,7 @@ elem.onscroll = (bits & 0x04000) ? @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null; elem.onload = (bits & 0x08000) ? - @com.google.gwt.user.client.impl.DOMImplStandard::dispatchUnhandledEvent : null; + @com.google.gwt.user.client.impl.DOMImplStandard::dispatchOnLoadEvent : null; elem.onerror = (bits & 0x10000) ? @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null; elem.onmousewheel = (bits & 0x20000) ?
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java index f40b951..ca0a226 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
@@ -39,7 +39,7 @@ private static JavaScriptObject dispatchEvent; @SuppressWarnings("unused") - private static JavaScriptObject dispatchUnhandledEvent; + private static JavaScriptObject dispatchOnLoadEvent; @Override public Element eventGetFromElement(Event evt) { @@ -167,8 +167,8 @@ return true; }); - @com.google.gwt.user.client.impl.DOMImplStandard::dispatchUnhandledEvent = $entry(function(evt) { - this.__gwtLastUnhandledEvent = evt.type; + @com.google.gwt.user.client.impl.DOMImplStandard::dispatchOnLoadEvent = $entry(function(evt) { + this.__gwtLastOnLoadEvent = evt.type; @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent.call(this, evt); }); @@ -248,7 +248,7 @@ if (chMask & 0x04000) elem.onscroll = (bits & 0x04000) ? @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null; if (chMask & 0x08000) elem.onload = (bits & 0x08000) ? - @com.google.gwt.user.client.impl.DOMImplStandard::dispatchUnhandledEvent : null; + @com.google.gwt.user.client.impl.DOMImplStandard::dispatchOnLoadEvent : null; if (chMask & 0x10000) elem.onerror = (bits & 0x10000) ? @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null; if (chMask & 0x20000) elem.onmousewheel = (bits & 0x20000) ?
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..4419056 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java
@@ -31,7 +31,7 @@ private static JavaScriptObject callDispatchDblClickEvent; @SuppressWarnings("unused") - private static JavaScriptObject callDispatchUnhandledEvent; + private static JavaScriptObject callDispatchOnLoadEvent; /** * Let every GWT app on the page preview the current event. If any app cancels @@ -154,8 +154,8 @@ } }); - var dispatchUnhandledEvent = $entry(function() { - this.__gwtLastUnhandledEvent = $wnd.event.type; + var dispatchOnLoadEvent = $entry(function() { + this.__gwtLastOnLoadEvent = $wnd.event.type; dispatchEvent.call(this); }); @@ -173,9 +173,9 @@ @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); + $wnd['__gwt_dispatchOnLoadEvent_' + moduleName] = dispatchOnLoadEvent; + @com.google.gwt.user.client.impl.DOMImplTrident::callDispatchOnLoadEvent = new Function('w', + 'return function() { w.__gwt_dispatchOnLoadEvent_' + 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 @@ -268,8 +268,13 @@ @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 (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); + } + } 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..0471176 100644 --- a/user/src/com/google/gwt/user/client/ui/Frame.java +++ b/user/src/com/google/gwt/user/client/ui/Frame.java
@@ -15,10 +15,16 @@ */ package com.google.gwt.user.client.ui; +import com.google.gwt.user.client.Event; + import com.google.gwt.dom.client.Document; 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 +43,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"; @@ -69,6 +75,8 @@ public Frame() { setElement(Document.get().createIFrameElement()); setStyleName(DEFAULT_STYLENAME); + + sinkEvents(Event.ONLOAD); } /** @@ -93,6 +101,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 addHandler(handler, LoadEvent.getType()); + } + + /** * Gets the URL of the frame's resource. * * @return the frame's URL
diff --git a/user/src/com/google/gwt/user/client/ui/Image.java b/user/src/com/google/gwt/user/client/ui/Image.java index b057c2c..04a28fc 100644 --- a/user/src/com/google/gwt/user/client/ui/Image.java +++ b/user/src/com/google/gwt/user/client/ui/Image.java
@@ -117,7 +117,7 @@ * The attribute that is set when an image fires a native load or error event * before it is attached. */ - private static final String UNHANDLED_EVENT_ATTR = "__gwtLastUnhandledEvent"; + private static final String UNHANDLED_EVENT_ATTR = "__gwtLastOnLoadEvent"; /** * Implementation of behaviors associated with the clipped state of an image.
diff --git a/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImpl.java b/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImpl.java index 9d112af..9a39dbf 100644 --- a/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImpl.java +++ b/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImpl.java
@@ -51,7 +51,7 @@ + (-top + "px"); String clippedImgHtml = "<img " - + "onload='this.__gwtLastUnhandledEvent=\"load\";' src='" + + "onload='this.__gwtLastOnLoadEvent=\"load\";' src='" + GWT.getModuleBaseURL() + "clear.cache.gif' style='" + style + "' border='0'>";
diff --git a/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java b/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java index 8895b68..5155253 100644 --- a/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java +++ b/user/src/com/google/gwt/user/client/ui/impl/ClippedImageImplIE6.java
@@ -115,7 +115,7 @@ */ String clippedImgHtml = "<gwt:clipper style=\"" + clipperStyle - + "\"><img onload='this.__gwtLastUnhandledEvent=\"load\";' src='" + + "\"><img onload='this.__gwtLastOnLoadEvent=\"load\";' src='" + moduleBaseUrlProtocol + "' onerror='if(window.__gwt_transparentImgHandler)window.__gwt_transparentImgHandler(this);else this.src=\"" + GWT.getModuleBaseURL() + "clear.cache.gif\"' style=\"" + imgStyle + "\" width=" + (left + width) + " height=" + (top + height)
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..7e315bb --- /dev/null +++ b/user/test/com/google/gwt/dom/public-test/iframetest.html
@@ -0,0 +1,10 @@ +<html> +<body> +IFRAME TEST +</body> +</html> +<html> +<body> +IFRAME TEST +</body> +</html> \ No newline at end of file