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; }-*/; }