Issues: 1546, 1778, 1788, 1804 (multi-module bug fixes)
Patch by: jgw, jason.essington, mmastrac, benjamin.vitale
Review by: scottb
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2661 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImpl.java b/user/src/com/google/gwt/user/client/impl/DOMImpl.java
index 298b8c9..ce4d7a6 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImpl.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImpl.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.user.client.impl;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
@@ -26,6 +27,28 @@
protected static boolean eventSystemIsInitialized;
+ /**
+ * Returns <code>true</code>if the object is an instance of EventListener
+ * and the object belongs to this module.
+ */
+ protected static boolean isMyListener(Object object) {
+ /*
+ * The first test ensures the Object belongs to this module in hosted mode,
+ * because this hosted mode class loader will have a different copy of
+ * the EventListener class than some other module would have.
+ *
+ * However, in web mode we could still get a collision where another module
+ * happens to use the same typeId. The second test ensures the Object is not
+ * "foreign". See Cast.isJavaScriptObject().
+ */
+ boolean b = object instanceof com.google.gwt.user.client.EventListener
+ && !(object instanceof JavaScriptObject);
+ if (!b) {
+ System.out.println(object.toString());
+ }
+ return b;
+ }
+
public native void eventCancelBubble(Event evt, boolean cancel) /*-{
evt.cancelBubble = cancel;
}-*/;
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 288a3d6..a3c7589 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplIE6.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.user.client.impl;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
@@ -24,12 +25,15 @@
*/
class DOMImplIE6 extends DOMImpl {
- /**
- * Referenced from JavaScript.
- */
@SuppressWarnings("unused")
private static Element currentEventTarget;
+ @SuppressWarnings("unused")
+ private static JavaScriptObject dispatchEvent;
+
+ @SuppressWarnings("unused")
+ private static JavaScriptObject dispatchDblClickEvent;
+
@Override
public native int eventGetClientX(Event evt) /*-{
return evt.clientX -
@@ -101,8 +105,7 @@
@Override
public native void initEventSystem() /*-{
- // Set up event dispatchers.
- $wnd.__dispatchEvent = function() {
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent = function() {
// IE doesn't define event.currentTarget, so we squirrel it away here. It
// also seems that IE won't allow you to add expandos to the event object,
// so we have to store it in a global. This is ok because only one event
@@ -119,33 +122,44 @@
}
var listener, curElem = this;
- while (curElem && !(listener = curElem.__listener))
+ while (curElem && !(listener = curElem.__listener)) {
curElem = curElem.parentElement;
+ }
- if (listener)
- @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)($wnd.event, curElem, listener);
+ if (listener) {
+ if (@com.google.gwt.user.client.impl.DOMImpl::isMyListener(Ljava/lang/Object;)(listener)) {
+ @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)($wnd.event, curElem, listener);
+ }
+ }
@com.google.gwt.user.client.impl.DOMImplIE6::currentEventTarget = oldEventTarget;
};
- $wnd.__dispatchDblClickEvent = function() {
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchDblClickEvent = function() {
var newEvent = $doc.createEventObject();
this.fireEvent('onclick', newEvent);
- if (this.__eventBits & 2)
- $wnd.__dispatchEvent.call(this);
+ if (this.__eventBits & 2) {
+ (@com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent)();
+ }
};
- $doc.body.onclick =
- $doc.body.onmousedown =
- $doc.body.onmouseup =
- $doc.body.onmousemove =
- $doc.body.onmousewheel =
- $doc.body.onkeydown =
- $doc.body.onkeypress =
- $doc.body.onkeyup =
- $doc.body.onfocus =
- $doc.body.onblur =
- $doc.body.ondblclick = $wnd.__dispatchEvent;
+ // 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().
+ var bodyDispatcher = function() { @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent.call($doc.body); };
+ var bodyDblClickDispatcher = function() { @com.google.gwt.user.client.impl.DOMImplIE6::dispatchDblClickEvent.call($doc.body); };
+
+ $doc.body.attachEvent('onclick', bodyDispatcher);
+ $doc.body.attachEvent('onmousedown', bodyDispatcher);
+ $doc.body.attachEvent('onmouseup', bodyDispatcher);
+ $doc.body.attachEvent('onmousemove', bodyDispatcher);
+ $doc.body.attachEvent('onmousewheel', bodyDispatcher);
+ $doc.body.attachEvent('onkeydown', bodyDispatcher);
+ $doc.body.attachEvent('onkeypress', bodyDispatcher);
+ $doc.body.attachEvent('onkeyup', bodyDispatcher);
+ $doc.body.attachEvent('onfocus', bodyDispatcher);
+ $doc.body.attachEvent('onblur', bodyDispatcher);
+ $doc.body.attachEvent('ondblclick', bodyDblClickDispatcher);
}-*/;
@Override
@@ -186,44 +200,44 @@
var chMask = (elem.__eventBits || 0) ^ bits;
elem.__eventBits = bits;
if (!chMask) return;
-
+
if (chMask & 0x00001) elem.onclick = (bits & 0x00001) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
// Add a ondblclick handler if onclick is desired to ensure that
// a user's double click will result in two onlclick events.
if (chMask & (0x00003)) elem.ondblclick = (bits & (0x00003)) ?
- $wnd.__dispatchDblClickEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchDblClickEvent : null;
if (chMask & 0x00004) elem.onmousedown = (bits & 0x00004) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00008) elem.onmouseup = (bits & 0x00008) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00010) elem.onmouseover = (bits & 0x00010) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00020) elem.onmouseout = (bits & 0x00020) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00040) elem.onmousemove = (bits & 0x00040) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00080) elem.onkeydown = (bits & 0x00080) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00100) elem.onkeypress = (bits & 0x00100) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00200) elem.onkeyup = (bits & 0x00200) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00400) elem.onchange = (bits & 0x00400) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x00800) elem.onfocus = (bits & 0x00800) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x01000) elem.onblur = (bits & 0x01000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x02000) elem.onlosecapture = (bits & 0x02000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x04000) elem.onscroll = (bits & 0x04000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x08000) elem.onload = (bits & 0x08000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x10000) elem.onerror = (bits & 0x10000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
if (chMask & 0x20000) elem.onmousewheel = (bits & 0x20000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplIE6::dispatchEvent : null;
}-*/;
}
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
index 9474037..c7b7734 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplMozilla.java
@@ -36,7 +36,7 @@
public native void sinkEventsMozilla(Element elem, int bits) /*-{
if (bits & 0x20000) {
- elem.addEventListener('DOMMouseScroll', $wnd.__dispatchEvent, false);
+ elem.addEventListener('DOMMouseScroll', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false);
}
}-*/;
@@ -69,7 +69,7 @@
true
);
- $wnd.addEventListener('DOMMouseScroll', $wnd.__dispatchCapturedMouseEvent,
+ $wnd.addEventListener('DOMMouseScroll', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent,
true);
}-*/;
}
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 9961511..31d7a4d 100644
--- a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
+++ b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -15,6 +15,7 @@
*/
package com.google.gwt.user.client.impl;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
@@ -25,6 +26,18 @@
*/
abstract class DOMImplStandard extends DOMImpl {
+ @SuppressWarnings("unused")
+ private static JavaScriptObject captureElem;
+
+ @SuppressWarnings("unused")
+ private static JavaScriptObject dispatchCapturedEvent;
+
+ @SuppressWarnings("unused")
+ private static JavaScriptObject dispatchCapturedMouseEvent;
+
+ @SuppressWarnings("unused")
+ private static JavaScriptObject dispatchEvent;
+
@Override
public native int eventGetButton(Event evt) /*-{
// Standard browsers and IE disagree on what the button codes for buttons
@@ -150,18 +163,19 @@
@Override
protected native void initEventSystem() /*-{
- // Set up capture event dispatchers.
- $wnd.__dispatchCapturedMouseEvent = function(evt) {
- if ($wnd.__dispatchCapturedEvent(evt)) {
- var cap = $wnd.__captureElem;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent = function(evt) {
+ if ((@com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedEvent)(evt)) {
+ var cap = @com.google.gwt.user.client.impl.DOMImplStandard::captureElem;
if (cap && cap.__listener) {
- @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)(evt, cap, cap.__listener);
- evt.stopPropagation();
+ if (@com.google.gwt.user.client.impl.DOMImpl::isMyListener(Ljava/lang/Object;)(cap.__listener)) {
+ @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)(evt, cap, cap.__listener);
+ evt.stopPropagation();
+ }
}
}
};
- $wnd.__dispatchCapturedEvent = function(evt) {
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedEvent = function(evt) {
if (!@com.google.gwt.user.client.DOM::previewEvent(Lcom/google/gwt/user/client/Event;)(evt)) {
evt.stopPropagation();
evt.preventDefault();
@@ -171,31 +185,34 @@
return true;
};
- $wnd.addEventListener('click', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('dblclick', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('mousedown', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('mouseup', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('mousemove', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('mouseover', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('mouseout', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('mousewheel', $wnd.__dispatchCapturedMouseEvent, true);
- $wnd.addEventListener('keydown', $wnd.__dispatchCapturedEvent, true);
- $wnd.addEventListener('keyup', $wnd.__dispatchCapturedEvent, true);
- $wnd.addEventListener('keypress', $wnd.__dispatchCapturedEvent, true);
-
- // Set up normal event dispatcher.
- $wnd.__dispatchEvent = function(evt) {
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent = function(evt) {
var listener, curElem = this;
- while (curElem && !(listener = curElem.__listener))
+ while (curElem && !(listener = curElem.__listener)) {
curElem = curElem.parentNode;
- if (curElem && curElem.nodeType != 1)
- curElem = null;
+ }
- if (listener)
- @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)(evt, curElem, listener);
+ if (curElem && curElem.nodeType != 1) {
+ curElem = null;
+ }
+
+ if (listener) {
+ if (@com.google.gwt.user.client.impl.DOMImpl::isMyListener(Ljava/lang/Object;)(listener)) {
+ @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/user/client/Element;Lcom/google/gwt/user/client/EventListener;)(evt, curElem, listener);
+ }
+ }
};
- $wnd.__captureElem = null;
+ $wnd.addEventListener('click', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('dblclick', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('mousedown', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('mouseup', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('mousemove', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('mouseover', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('mouseout', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('mousewheel', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true);
+ $wnd.addEventListener('keydown', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedEvent, true);
+ $wnd.addEventListener('keyup', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedEvent, true);
+ $wnd.addEventListener('keypress', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedEvent, true);
}-*/;
protected native void sinkEventsImpl(Element elem, int bits) /*-{
@@ -204,50 +221,50 @@
if (!chMask) return;
if (chMask & 0x00001) elem.onclick = (bits & 0x00001) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00002) elem.ondblclick = (bits & 0x00002) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00004) elem.onmousedown = (bits & 0x00004) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00008) elem.onmouseup = (bits & 0x00008) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00010) elem.onmouseover = (bits & 0x00010) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00020) elem.onmouseout = (bits & 0x00020) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00040) elem.onmousemove = (bits & 0x00040) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00080) elem.onkeydown = (bits & 0x00080) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00100) elem.onkeypress = (bits & 0x00100) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00200) elem.onkeyup = (bits & 0x00200) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00400) elem.onchange = (bits & 0x00400) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x00800) elem.onfocus = (bits & 0x00800) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x01000) elem.onblur = (bits & 0x01000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x02000) elem.onlosecapture = (bits & 0x02000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x04000) elem.onscroll = (bits & 0x04000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x08000) elem.onload = (bits & 0x08000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x10000) elem.onerror = (bits & 0x10000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
if (chMask & 0x20000) elem.onmousewheel = (bits & 0x20000) ?
- $wnd.__dispatchEvent : null;
+ @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
}-*/;
private native void releaseCaptureImpl(Element elem) /*-{
- if (elem === $wnd.__captureElem) {
- $wnd.__captureElem = null;
+ if (elem === @com.google.gwt.user.client.impl.DOMImplStandard::captureElem) {
+ @com.google.gwt.user.client.impl.DOMImplStandard::captureElem = null;
}
}-*/;
private native void setCaptureImpl(Element elem) /*-{
- $wnd.__captureElem = elem;
+ @com.google.gwt.user.client.impl.DOMImplStandard::captureElem = elem;
}-*/;
}