Fixed a bug where IE would synthesize extra click events on a double click.
Patch by: jlabanca
Review by: jgw (desk)
Issue: 3392
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4910 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
index d071853..03e937c 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
@@ -108,9 +108,16 @@
@com.google.gwt.user.client.impl.DOMImplIE6::dispatchDblClickEvent = function() {
var newEvent = $doc.createEventObject();
- $wnd.event.srcElement.fireEvent('onclick', newEvent);
+ // Synthesize a click event if one hasn't already been synthesized.
+ if ($wnd.event.returnValue == null) {
+ $wnd.event.srcElement.fireEvent('onclick', newEvent);
+ }
if (this.__eventBits & 2) {
@com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent.call(this);
+ } else if ($wnd.event.returnValue == null) {
+ // Ensure that we preview the event even if we aren't handling it.
+ $wnd.event.returnValue = true;
+ @com.google.gwt.user.client.DOM::previewEvent(Lcom/google/gwt/user/client/Event;)($wnd.event);
}
};
diff --git a/user/test/com/google/gwt/user/client/EventTest.java b/user/test/com/google/gwt/user/client/EventTest.java
index 1ed7e7b..a8d6474 100644
--- a/user/test/com/google/gwt/user/client/EventTest.java
+++ b/user/test/com/google/gwt/user/client/EventTest.java
@@ -15,10 +15,19 @@
*/
package com.google.gwt.user.client;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.DoubleClickEvent;
+import com.google.gwt.event.dom.client.DoubleClickHandler;
+import com.google.gwt.event.dom.client.HasDoubleClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RootPanel;
/**
* Test Case for {@link Event}.
@@ -88,6 +97,23 @@
}
}
+ /**
+ * A custom {@link Label} used for testing.
+ */
+ private static class TestLabel extends Label implements
+ HasDoubleClickHandlers {
+ public HandlerRegistration addDoubleClickHandler(DoubleClickHandler handler) {
+ return addDomHandler(handler, DoubleClickEvent.getType());
+ }
+ }
+
+ /**
+ * Debug information used to test events.
+ */
+ private static class EventInfo {
+ private int fireCount = 0;
+ }
+
@Override
public String getModuleName() {
return "com.google.gwt.user.User";
@@ -124,8 +150,48 @@
}
/**
- * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
- * value if the native event is canceled.
+ * Test that a double click results in exactly two click events, one real and
+ * one simulated. See issue 3392 for more info.
+ */
+ public void testDoubleClickEvent() {
+ TestLabel label = new TestLabel();
+ RootPanel.get().add(label);
+
+ // Add some handlers
+ final EventInfo clickInfo = new EventInfo();
+ label.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ clickInfo.fireCount++;
+ }
+ });
+ final EventInfo dblclickInfo = new EventInfo();
+ label.addDoubleClickHandler(new DoubleClickHandler() {
+ public void onDoubleClick(DoubleClickEvent event) {
+ dblclickInfo.fireCount++;
+ }
+ });
+
+ // Fire a click event
+ NativeEvent clickEvent = Document.get().createClickEvent(0, 0, 0, 0, 0,
+ false, false, false, false);
+ label.getElement().dispatchEvent(clickEvent);
+ NativeEvent dblclickEvent = Document.get().createDblClickEvent(0, 0, 0, 0,
+ 0, false, false, false, false);
+ label.getElement().dispatchEvent(dblclickEvent);
+
+ // Verify the results
+ if (isInternetExplorer()) {
+ assertEquals(2, clickInfo.fireCount);
+ } else {
+ assertEquals(1, clickInfo.fireCount);
+ }
+ assertEquals(1, dblclickInfo.fireCount);
+ RootPanel.get().remove(label);
+ }
+
+ /**
+ * Test that {@link Event#fireNativePreviewEvent(NativeEvent)} returns the
+ * correct value if the native event is canceled.
*/
public void testFireNativePreviewEventCancel() {
TestNativePreviewHandler handler0 = new TestNativePreviewHandler(true,
@@ -142,9 +208,9 @@
}
/**
- * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
- * value if the native event is prevented from being canceled, even if another
- * handler cancels the event.
+ * Test that {@link Event#fireNativePreviewEvent(NativeEvent)} returns the
+ * correct value if the native event is prevented from being canceled, even if
+ * another handler cancels the event.
*/
public void testFireNativePreviewEventPreventCancel() {
TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
@@ -161,9 +227,9 @@
}
/**
- * Test that {@link Event#fireNativePreviewEvent(Event)} fires handlers in
- * reverse order, and that the legacy EventPreview fires only if it is at the
- * top of the stack.
+ * Test that {@link Event#fireNativePreviewEvent(NativeEvent)} fires handlers
+ * in reverse order, and that the legacy EventPreview fires only if it is at
+ * the top of the stack.
*/
@SuppressWarnings("deprecation")
public void testFireNativePreviewEventReverseOrder() {
@@ -254,8 +320,8 @@
}
/**
- * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
- * value if the native event is not canceled.
+ * Test that {@link Event#fireNativePreviewEvent(NativeEvent)} returns the
+ * correct value if the native event is not canceled.
*/
public void testFireNativePreviewEventWithoutCancel() {
TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
@@ -272,8 +338,8 @@
}
/**
- * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
- * value if no handlers are present.
+ * Test that {@link Event#fireNativePreviewEvent(NativeEvent)} returns the
+ * correct value if no handlers are present.
*/
public void testFireNativePreviewEventWithoutHandlers() {
assertTrue(Event.fireNativePreviewEvent(null));
@@ -451,4 +517,8 @@
handler1.assertIsFired(true);
reg1.removeHandler();
}
+
+ private native boolean isInternetExplorer() /*-{
+ return navigator.userAgent.toLowerCase().indexOf("msie") != -1;
+ }-*/;
}